home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / program / oxcc1434.zip / SRC / BTERP.C < prev    next >
C/C++ Source or Header  |  1996-09-03  |  70KB  |  2,883 lines

  1. /* 
  2.     bterp.c -- v1.430 interpreter prototype for oxcc byte codes
  3.  
  4.     Copyright (c) 1995
  5.     Norman D. Culver dba
  6.     Oxbow Software
  7.     1323 S.E. 17th Street #662
  8.     Ft. Lauderdale, FL 33316
  9.     (954) 463-4754
  10.     ndc@icanect.net
  11.     All rights reserved.
  12.  
  13.  * Redistribution and use in source and binary forms are permitted
  14.  * provided that: (1) source distributions retain this entire copyright
  15.  * notice and comment, and (2) distributions including binaries display
  16.  * the following acknowledgement:  ``This product includes software
  17.  * developed by Norman D. Culver dba Oxbow Software''
  18.  * in the documentation or other materials provided with the distribution
  19.  * and in all advertising materials mentioning features or use of this
  20.  * software.
  21.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  22.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  23.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  24.  
  25. */
  26.  
  27. #define SUPPORT_LONG_LONG 1
  28. #define SUPPORT_LONG_DOUBLE 1
  29.  
  30. #define NEED_BYTECODES 1
  31. #define NEED_AOUT_FORMAT 1
  32. #include "oxbytes.h"
  33.  
  34. #define NEED_FUNCTHUNK 1
  35. #include "oxanf.h"
  36. #include <stdlib.h>
  37. #include <setjmp.h>
  38. #include <stdio.h>
  39.  
  40. #define PROG bterp
  41. #define USING_FRAMEWORK 1
  42.  
  43. #define SWITCHMOD 1009
  44. typedef struct _key
  45. {
  46.     unsigned long k[2];
  47.     unsigned long hv;
  48. } KEY, *KEYP;
  49.  
  50. typedef struct _nodeS
  51. {
  52.     unsigned long value;
  53.     unsigned long key[2];
  54.     struct _nodeS *fptr;
  55. } NodeS, *NodePS;
  56.  
  57. typedef struct _callblk {
  58.     void *loc;
  59.     char *es;
  60.     unsigned short argofs;
  61.     unsigned short flags;
  62.     long argsiz;
  63.     char *base_stack;            /* must be last element */
  64. } *PCB;
  65.  
  66. typedef struct _stakblk {
  67.     void *backlink;
  68.     long first_loc;
  69.     long last_loc;
  70.     char *cbes;
  71.     void *thunkaddr;
  72.     int stksize;
  73. } SB, *PSB;
  74.  
  75. typedef struct _fe {
  76.     char *filename;
  77.     long string_size;
  78.     char *strings;
  79.     char *text_start_address;
  80.     char *data_start_address;
  81.     char *bss_start_address;
  82. } *FE;
  83.  
  84. typedef struct _iv {
  85.     struct _iv *piv;
  86.     char *text_base;
  87.     char *dd;
  88.     void **struclist;
  89.     long slcnt;
  90.     long strretcnt;
  91.     void *allocalist;
  92.     NodePS *swtable;
  93.     char *chunkbase;
  94.     void *chunklist;
  95.     long chunksize;
  96.     FE entry;
  97.     char *filename;
  98.     char *funcptr;
  99.     Pft ft;
  100.     long funcaddr;
  101.     long stksiz;
  102.     long argsiz;
  103.     long maxes;
  104.     char *base_stack;
  105.     char *e_stack;
  106.     jmp_buf jb;
  107. #define MAX_RUNARGS 15
  108.     long run_argcnt;
  109.     char *run_args[MAX_RUNARGS];
  110.     int debug;
  111. } *Piv;
  112.  
  113. typedef struct _retval {
  114.     void *ptr;
  115.     long p1;
  116.     long p2;
  117. } RV;
  118.  
  119. int cfeprintf(const char *fmt, ...);
  120.  
  121. void _ExternCall();
  122. void _ExternCallS();
  123. void *oxlink_load_bare_symb(const char *symb, int dynlink);
  124. void *oxlink_find_bare_func(const char *);
  125. void *oxlink_find_func(const char *);
  126. int oxlink_load_file(const char *);
  127. int oxlink_load_object(const char *);
  128. int oxlink_unload_file(const char *, int);
  129. void oxlink_demand_load(void);
  130. void oxlink_demand_noload(void);
  131. void *oxlink_get_entry_struct(const char *filename);
  132. char *oxlink_errstr(void);
  133.  
  134. static void* bterp_eval();
  135.  
  136. #define SZ (20)    /* size of evaluation stack frame */
  137.  
  138. #define MIN(a,b) ((a<b)?a:b)
  139.  
  140. #define SRC(a) (a<<4)
  141. #define G1(a) ((unsigned long)*((unsigned char*)(a)))
  142. #define G2(a) ((unsigned long)*((unsigned short*)(a)))
  143. #define G3(a) (*((unsigned long*)(a))&0x00ffffff)
  144. #define G4(a) (*((unsigned long*)(a)))
  145. #define G8(a) (*((double*)(a)))
  146. #define GX(a) (*((long double*)(a)))
  147. #define GP1(a) ((long)*((char*)(a)))
  148. #define GP2(a) ((long)*((short*)(a)))
  149. #define GP3(a) ((*((long*)(a))<<8)>>8)
  150. #define GP4(a) (*((long*)(a)))
  151.  
  152. #define NEG_ES(t) {*((t*)es)=-(*((t*)es));break;}
  153. #define NOT_ES(t) {*((t*)es)=!(*((t*)es));break;}
  154. #define NOT_ES1 {*es=(((long*)es)[0]==0&&((long*)es)[1]==0)?1:0;}
  155. #define COMP_ES(t) {*((t*)es)=~(*((t*)es));break;}
  156. #define TRUTH_ES(t) {*((long*)es)=(*((t*)es))?1:0;break;}
  157. #define TRUTH_ES1 {*((long*)es)=(((long*)es)[0]==0&&((long*)es)[1]==0)?0:1;}
  158. #define GT_ES(t) {*((long*)oes)=(*((t*)oes)>*((t*)es))?1:0;es=oes;break;}
  159. #define LT_ES(t) {*((long*)oes)=(*((t*)oes)<*((t*)es))?1:0;es=oes;break;}
  160. #define GE_ES(t) {*((long*)oes)=(*((t*)oes)>=*((t*)es))?1:0;es=oes;break;}
  161. #define LE_ES(t) {*((long*)oes)=(*((t*)oes)<=*((t*)es))?1:0;es=oes;break;}
  162. #define NE_ES(t) {*((long*)oes)=(*((t*)oes)!=*((t*)es))?1:0;es=oes;break;}
  163. #define EQ_ES(t) {*((long*)oes)=(*((t*)oes)==*((t*)es))?1:0;es=oes;break;}
  164. #define ADD_ES(t) {*((t*)oes)+=*((t*)es);es=oes;break;}
  165. #define SUB_ES(t) {*((t*)oes)-=*((t*)es);es=oes;break;}
  166. #define MUL_ES(t) {*((t*)oes)*=*((t*)es);es=oes;break;}
  167. #define DIV_ES(t) {*((t*)oes)/=*((t*)es);es=oes;break;}
  168. #define OR_ES(t)  {*((t*)oes)|=*((t*)es);es=oes;break;}
  169. #define AND_ES(t) {*((t*)oes)&=*((t*)es);es=oes;break;}
  170. #define XOR_ES(t) {*((t*)oes)^=*((t*)es);es=oes;break;}
  171. #define MOD_ES(t) {*((t*)oes)%=*((unsigned long*)es);es=oes;break;}
  172. #define MODL_ES(t) {*((t*)oes)%=*((unsigned long long*)es);es=oes;break;}
  173. #define MODI_ES(t) {*((t*)es)%=*((unsigned short*)np);pc+=2;break;}
  174. #define RSH_ES(t) {*((t*)oes)>>=*((unsigned char*)es);es=oes;break;}
  175. #define LSH_ES(t) {*((t*)oes)<<=*((unsigned char*)es);es=oes;break;}
  176. #define RSHI_ES(t) {*((t*)es)>>=*np;pc+=1;break;}
  177. #define LSHI_ES(t) {*((t*)es)<<=*np;pc+=1;break;}
  178. #define DEREF_ES(t) {*((long*)es)=**((t**)es);break;}
  179. #define UDEREF_ES(t) {*((unsigned long*)es)=**((t**)es);break;}
  180. #define FDEREF_ES(t) {*((t*)es)=**((t**)es);break;}
  181. #define DEREF1_ES(t) {*((long*)nes)=**((t**)es);es=nes;break;}
  182. #define UDEREF1_ES(t) {*((unsigned long*)nes)=**((t**)es);es=nes;break;}
  183. #define FDEREF1_ES(t) {*((t*)nes)=**((t**)es);es=nes;break;}
  184. #define SIGNE if(*(es+3)&0x80)*((long*)(es+4))=-1;else *((long*)(es+4))=0
  185. #define USIGNE *((long*)(es+4))=0
  186. #define LOADI1() {*((long*)nes)=GP1(np);es=nes;SIGNE;pc+=1;break;}
  187. #define LOADI2() {*((long*)nes)=GP2(np);es=nes;SIGNE;pc+=2;break;}
  188. #define LOADI4() {*((long*)nes)=GP4(np);es=nes;SIGNE;pc+=4;break;}
  189. #define LOADUI1() {*((unsigned long*)nes)=G1(np);es=nes;USIGNE;pc+=1;break;}
  190. #define LOADUI2() {*((unsigned long*)nes)=G2(np);es=nes;USIGNE;pc+=2;break;}
  191. #define LOADUI4() {*((unsigned long*)nes)=G4(np);es=nes;USIGNE;pc+=4;break;}
  192. #define LOADI8() {*((double*)nes)=G8(np);es=nes;pc+=8;break;}
  193. #define LOADIX() {*((long double*)nes)=GX(np);es=nes;pc+=XSZ;break;}
  194.  
  195. #define LOADADDRI1() {*((unsigned long*)nes)=(G1(np)<<2);es=nes;pc+=1;break;}
  196. #define LOADADDRI2() {*((unsigned long*)nes)=(G2(np)<<2);es=nes;pc+=2;break;}
  197. #define LOADADDRI3() {*((unsigned long*)nes)=(G3(np));es=nes;pc+=3;break;}
  198. #define LOADADDRI4() {*((unsigned long*)nes)=G4(np);es=nes;pc+=4;break;}
  199.  
  200. #define LOADSTK1(t) {*((t*)nes)=*((t*)(fs+(G1(np)<<2)));es=nes;pc+=1;break;}
  201. #define LOADSTK2(t) {*((t*)nes)=*((t*)(fs+(G2(np)<<2)));es=nes;pc+=2;break;}
  202. #define LOADSTK3(t) {*((t*)nes)=*((t*)(fs+(G3(np))));es=nes;pc+=3;break;}
  203.  
  204. #define STORSTK1(t) {*((t*)(fs+(G1(np)<<2)))=*((t*)es);es=oes;pc+=1;break;}
  205. #define STORSTK2(t) {*((t*)(fs+(G2(np)<<2)))=*((t*)es);es=oes;pc+=2;break;}
  206. #define STORSTK3(t) {*((t*)(fs+(G3(np)<<0)))=*((t*)es);es=oes;pc+=3;break;}
  207.  
  208. #define STORSTKI1(t) {*((t*)(fs+(G1(np)<<2)))=*((t*)(np+1));pc+=sizeof(t)+1;break;}
  209. #define STORSTKI2(t) {*((t*)(fs+(G2(np)<<2)))=*((t*)(np+2));pc+=sizeof(t)+2;break;}
  210. #define STORSTKI3(t) {*((t*)(fs+(G3(np)<<0)))=*((t*)(np+3));pc+=sizeof(t)+3;break;}
  211.  
  212. #define LOADMEM1(t) {*((t*)nes)=*((t*)(dd+(G1(np)<<2)));es=nes;pc+=1;break;}
  213. #define LOADMEM2(t) {*((t*)nes)=*((t*)(dd+(G2(np)<<2)));es=nes;pc+=2;break;}
  214. #define LOADMEM3(t) {*((t*)nes)=*((t*)(dd+(G3(np))));es=nes;pc+=3;break;}
  215. #define LOADMEM4(t) {*((t*)nes)=*((t*)((void*)G4(np)));es=nes;pc+=4;break;}
  216.  
  217. #define STORMEM1(t) {*((t*)(dd+(G1(np)<<2)))=*((t*)es);es=oes;pc+=1;break;}
  218. #define STORMEM2(t) {*((t*)(dd+(G2(np)<<2)))=*((t*)es);es=oes;pc+=2;break;}
  219. #define STORMEM3(t) {*((t*)(dd+(G3(np)<<2)))=*((t*)es);es=oes;pc+=3;break;}
  220. #define STORMEM4(t) {*((t*)((void*)G4(np)))=*((t*)es);es=oes;pc+=4;break;}
  221.  
  222. #define STORMEMI1(t) {*((t*)(dd+(G1(np)<<2)))=*((t*)(np+1));pc+=sizeof(t)+1;break;}
  223. #define STORMEMI2(t) {*((t*)(dd+(G2(np)<<2)))=*((t*)(np+2));pc+=sizeof(t)+2;break;}
  224. #define STORMEMI3(t) {*((t*)(dd+(G3(np)<<0)))=*((t*)(np+3));pc+=sizeof(t)+3;break;}
  225. #define STORMEMI4(t) {*((t*)((void*)G4(np)))=*((t*)(np+4));pc+=sizeof(t)+4;break;}
  226.  
  227. static unsigned long bfields[33] = {
  228.     0x00000000,0x00000001,0x00000003,0x00000007,
  229.     0x0000000f,0x0000001f,0x0000003f,0x0000007f,
  230.     0x000000ff,0x000001ff,0x000003ff,0x000007ff,
  231.     0x00000fff,0x00001fff,0x00003fff,0x00007fff,
  232.     0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
  233.     0x000fffff,0x001fffff,0x003fffff,0x007fffff,
  234.     0x00ffffff,0x01ffffff,0x03ffffff,0x07ffffff,
  235.     0x0fffffff,0x1fffffff,0x3fffffff,0x7fffffff,
  236.     0xfffffff
  237.     };
  238. static unsigned long tsfields[33] = {
  239.     0x00000000,0x00000001,0x00000002,0x00000004,
  240.     0x00000008,0x00000010,0x00000020,0x00000040,
  241.     0x00000080,0x00000100,0x00000200,0x00000400,
  242.     0x00000800,0x00001000,0x00002000,0x00004000,
  243.     0x00008000,0x00010000,0x00020000,0x00040000,
  244.     0x00080000,0x00100000,0x00200000,0x00400000,
  245.     0x00800000,0x01000000,0x02000000,0x04000000,
  246.     0x08000000,0x10000000,0x20000000,0x40000000,
  247.     0x80000000
  248.     };
  249. static unsigned long sfields[33] = {
  250.     0x00000000,0xfffffffe,0xfffffffc,0xfffffff8,
  251.     0xfffffff0,0xffffffe0,0xffffffc0,0xffffff80,
  252.     0xffffff00,0xfffffe00,0xfffffc00,0xfffff800,
  253.     0xfffff000,0xffffe000,0xffffc000,0xffff8000,
  254.     0xffff0000,0xfffe0000,0xfffc0000,0xfff80000,
  255.     0xfff00000,0xffe00000,0xffc00000,0xff800000,
  256.     0xff000000,0xfe000000,0xfc000000,0xf8000000,
  257.     0xf0000000,0xe0000000,0xc0000000,0x80000000,
  258.     0x80000000
  259.     };
  260. #if SUPPORT_LONG_LONG
  261. static unsigned long long lbfields[65] = {
  262.     0x0000000000000000LL,0x0000000000000001LL,0x0000000000000003LL,0x0000000000000007LL,
  263.     0x000000000000000fLL,0x000000000000001fLL,0x000000000000003fLL,0x000000000000007fLL,
  264.     0x00000000000000ffLL,0x00000000000001ffLL,0x00000000000003ffLL,0x00000000000007ffLL,
  265.     0x0000000000000fffLL,0x0000000000001fffLL,0x0000000000003fffLL,0x0000000000007fffLL,
  266.     0x000000000000ffffLL,0x000000000001ffffLL,0x000000000003ffffLL,0x000000000007ffffLL,
  267.     0x00000000000fffffLL,0x00000000001fffffLL,0x00000000003fffffLL,0x00000000007fffffLL,
  268.     0x0000000000ffffffLL,0x0000000001ffffffLL,0x0000000003ffffffLL,0x0000000007ffffffLL,
  269.     0x000000000fffffffLL,0x000000001fffffffLL,0x000000003fffffffLL,0x000000007fffffffLL,
  270.     0x00000000ffffffffLL,0x00000001ffffffffLL,0x00000003ffffffffLL,0x00000007ffffffffLL,
  271.     0x0000000fffffffffLL,0x0000001fffffffffLL,0x0000003fffffffffLL,0x0000007fffffffffLL,
  272.     0x000000ffffffffffLL,0x000001ffffffffffLL,0x000003ffffffffffLL,0x000007ffffffffffLL,
  273.     0x00000fffffffffffLL,0x00001fffffffffffLL,0x00003fffffffffffLL,0x00007fffffffffffLL,
  274.     0x0000ffffffffffffLL,0x0001ffffffffffffLL,0x0003ffffffffffffLL,0x0007ffffffffffffLL,
  275.     0x000fffffffffffffLL,0x001fffffffffffffLL,0x003fffffffffffffLL,0x007fffffffffffffLL,
  276.     0x00ffffffffffffffLL,0x01ffffffffffffffLL,0x03ffffffffffffffLL,0x07ffffffffffffffLL,
  277.     0x0fffffffffffffffLL,0x1fffffffffffffffLL,0x3fffffffffffffffLL,0x7fffffffffffffffLL,
  278.     0xfffffffffffffffLL
  279.     };
  280. static unsigned long long ltsfields[65] = {
  281.     0x0000000000000000LL,0x0000000000000001LL,0x0000000000000002LL,0x0000000000000004LL,
  282.     0x0000000000000008LL,0x0000000000000010LL,0x0000000000000020LL,0x0000000000000040LL,
  283.     0x0000000000000080LL,0x0000000000000100LL,0x0000000000000200LL,0x0000000000000400LL,
  284.     0x0000000000000800LL,0x0000000000001000LL,0x0000000000002000LL,0x0000000000004000LL,
  285.     0x0000000000008000LL,0x0000000000010000LL,0x0000000000020000LL,0x0000000000040000LL,
  286.     0x0000000000080000LL,0x0000000000100000LL,0x0000000000200000LL,0x0000000000400000LL,
  287.     0x0000000000800000LL,0x0000000001000000LL,0x0000000002000000LL,0x0000000004000000LL,
  288.     0x0000000008000000LL,0x0000000010000000LL,0x0000000020000000LL,0x0000000040000000LL,
  289.     0x0000000080000000LL,0x0000000100000000LL,0x0000000200000000LL,0x0000000400000000LL,
  290.     0x0000000800000000LL,0x0000001000000000LL,0x0000002000000000LL,0x0000004000000000LL,
  291.     0x0000008000000000LL,0x0000010000000000LL,0x0000020000000000LL,0x0000040000000000LL,
  292.     0x0000080000000000LL,0x0000100000000000LL,0x0000200000000000LL,0x0000400000000000LL,
  293.     0x0000800000000000LL,0x0001000000000000LL,0x0002000000000000LL,0x0004000000000000LL,
  294.     0x0008000000000000LL,0x0010000000000000LL,0x0020000000000000LL,0x0040000000000000LL,
  295.     0x0080000000000000LL,0x0100000000000000LL,0x0200000000000000LL,0x0400000000000000LL,
  296.     0x0800000000000000LL,0x1000000000000000LL,0x2000000000000000LL,0x4000000000000000LL,
  297.     0x8000000000000000LL
  298.     };
  299. static unsigned long long lsfields[65] = {
  300.     0x0000000000000000LL,0xfffffffffffffffeLL,0xfffffffffffffffcLL,0xfffffffffffffff8LL,
  301.     0xfffffffffffffff0LL,0xffffffffffffffe0LL,0xffffffffffffffc0LL,0xffffffffffffff80LL,
  302.     0xffffffffffffff00LL,0xfffffffffffffe00LL,0xfffffffffffffc00LL,0xfffffffffffff800LL,
  303.     0xfffffffffffff000LL,0xffffffffffffe000LL,0xffffffffffffc000LL,0xffffffffffff8000LL,
  304.     0xffffffffffff0000LL,0xfffffffffffe0000LL,0xfffffffffffc0000LL,0xfffffffffff80000LL,
  305.     0xfffffffffff00000LL,0xffffffffffe00000LL,0xffffffffffc00000LL,0xffffffffff800000LL,
  306.     0xffffffffff000000LL,0xfffffffffe000000LL,0xfffffffffc000000LL,0xfffffffff8000000LL,
  307.     0xfffffffff0000000LL,0xffffffffe0000000LL,0xffffffffc0000000LL,0xffffffff80000000LL,
  308.     0xffffffff00000000LL,0xfffffffe00000000LL,0xfffffffc00000000LL,0xfffffff800000000LL,
  309.     0xfffffff000000000LL,0xffffffe000000000LL,0xffffffc000000000LL,0xffffff8000000000LL,  
  310.     0xffffff0000000000LL,0xfffffe0000000000LL,0xfffffc0000000000LL,0xfffff80000000000LL,
  311.     0xfffff00000000000LL,0xffffe00000000000LL,0xffffc00000000000LL,0xffff800000000000LL,
  312.     0xffff000000000000LL,0xfffe000000000000LL,0xfffc000000000000LL,0xfff8000000000000LL,
  313.     0xfff0000000000000LL,0xffe0000000000000LL,0xffc0000000000000LL,0xff80000000000000LL,
  314.     0xff00000000000000LL,0xfe00000000000000LL,0xfc00000000000000LL,0xf800000000000000LL,
  315.     0xf000000000000000LL,0xe000000000000000LL,0xc000000000000000LL,0x8000000000000000LL,
  316.     0x8000000000000000LL
  317.     };
  318. #endif /* SUPPORT_LONG_LONG */
  319.  
  320. static char thunk386[41] =
  321. {/* THE EXTERNAL CALLBACK THUNK (Intel 386) */
  322.     0x55,                /* pushl %ebp */
  323.     0x89,0xE5,            /* movl %esp,%ebp */
  324.     0x68,0,0,0,0,        /* pushl ft */
  325.     0x68,0,0,0,0,        /* pushl iv */
  326.     0x68,0,0,0,0,        /* pushl base_stack */
  327.     0x83,0xEC,0x0C,        /* subl $12,%esp (RETVAL) */
  328.     0xB8,0,0,0,0,        /* movl _bterp_handle_callbacks,%eax */
  329.     0xFF,0xD0,            /* call *%eax */
  330.     0x8B,0x04,0x24,        /* movl (%esp),%eax     */
  331.     0x8B,0x54,0x24,0x04,/* movl 4(%esp),%edx */
  332.     0x8B,0x4C,0x24,0x08,/* movl 8(%esp),%ecx */
  333.     0xC9,                /* leave */
  334.     0xC3                /* ret */
  335. };
  336. static char thunk386S[42] =
  337. {/* THE EXTERNAL CALLBACK THUNK (Intel 386) */
  338.     0x55,                /* pushl %ebp */
  339.     0x89,0xE5,            /* movl %esp,%ebp */
  340.     0x68,0,0,0,0,        /* pushl ft */
  341.     0x68,0,0,0,0,        /* pushl iv */
  342.     0x68,0,0,0,0,        /* pushl base_stack */
  343.     0x83,0xEC,0x0C,        /* subl $12,%esp (RETVAL) */
  344.     0xB8,0,0,0,0,        /* movl _bterp_handle_callbacks,%eax */
  345.     0xFF,0xD0,            /* call *%eax */
  346.     0x8B,0x04,0x24,        /* movl (%esp),%eax     */
  347.     0x8B,0x54,0x24,0x04,/* movl 4(%esp),%edx */
  348.     0x8B,0x4C,0x24,0x08,/* movl 8(%esp),%ecx */
  349.     0xC9,                /* leave */
  350.     0xC2,0x04            /* ret $4 (prune structret arg, GCC convention) */
  351. };
  352.  
  353.  
  354.  
  355. /* ========================== INTERPRETER CODE =========================== */
  356.  
  357. static int
  358. findswitch(Piv iv, unsigned long *key, void *result)
  359. {
  360. int bin;
  361. NodePS node;
  362.     bin = (((~key[0] ^ key[1]) * 1103515245UL) + 12345) % SWITCHMOD;
  363.     if((node = iv->swtable[bin]))
  364.     {
  365.         do {
  366.             if(node->key[0] == key[0] && node->key[1] == key[1])
  367.             {
  368.                 *((NodePS*)result) = node;
  369.                 return 1;
  370.             }
  371.         } while((node = node->fptr));
  372.     }
  373.     return 0;
  374. }
  375. static void *
  376. new_Snode(Piv iv)
  377. {
  378. void *p;
  379.  
  380.     if(iv->chunksize < sizeof(NodeS))
  381.     {
  382.         iv->chunkbase = calloc(1, 4088);
  383.         *((void**)iv->chunkbase) = iv->chunklist;
  384.         iv->chunklist = iv->chunkbase;
  385.         iv->chunkbase += sizeof(void*);
  386.         iv->chunksize = 4088 - sizeof(void*);
  387.     }
  388.     p = iv->chunkbase;
  389.     iv->chunkbase += sizeof(NodeS);
  390.     iv->chunksize -= sizeof(NodeS);
  391.     return p;
  392. }
  393. static void
  394. saveswitch(Piv iv, unsigned long *key, long value)
  395. {
  396. int bin;
  397. NodePS node;
  398.  
  399.     bin = (((~key[0] ^ key[1]) * 1103515245UL) + 12345) % SWITCHMOD;
  400.     node = new_Snode(iv);
  401.     node->key[0] = key[0];
  402.     node->key[1] = key[1];
  403.     node->value = value;
  404.     node->fptr = iv->swtable[bin];
  405.     iv->swtable[bin] = node;
  406. }
  407. static void
  408. purge_allocas(Piv iv, void *last)
  409. {
  410.     while(iv->allocalist && (iv->allocalist != last))
  411.     {
  412.     void *this = iv->allocalist;
  413.         iv->allocalist = *((void**)this);
  414.         free(this);
  415.     }
  416. }
  417.  
  418. static void
  419. _bterp_handle_callbacks(RV retval, char *base_stack, Piv iv, Pft ft, 
  420.                             int ebp, int pret, ...)
  421. {/* Call to interpreted function from external function */
  422. unsigned short fmods;
  423. long stksiz, maxes, strucsiz, fs_size, argofs, es_beg, argsiz;
  424. int hidden;
  425. void *strret = 0;
  426. void *argaddr, *e_stack, *lastalloca;
  427. void *pes;
  428. DATUM lastval;
  429.  
  430.     fmods = ft->fmods;
  431.     argaddr = ((long*)&pret)+1;
  432.     if((hidden = (fmods & Fretstr)))
  433.     {/* return a struct or union */
  434.         strucsiz = ft->retsiz<<2;
  435.         strret = (void*) *(((long*)&pret)+1);
  436.     }
  437.     stksiz = ft->stksiz<<2;
  438.     maxes = ft->maxes;
  439.     argsiz = ft->argsiz<<2;
  440.  
  441.     if(fmods & Fnested)
  442.     {/* callback to nested function */
  443.         argofs = ft->stkbeg+(stksiz-argsiz-hidden);
  444.         e_stack = ((PSB)base_stack)->cbes;
  445.     }
  446.     else
  447.     {/* callback to non-nested function */
  448.         if(fmods & Fellipsis)
  449.             argsiz += 128;
  450.         es_beg = stksiz+hidden+argsiz;
  451.         argofs = stksiz;
  452.         fs_size = es_beg + ((maxes+6)*SZ);
  453.  
  454.         /* Create a stack for the called function */
  455.         base_stack = calloc(1, fs_size + sizeof(SB));
  456.         e_stack = base_stack + sizeof(SB) + es_beg;
  457.         ((PSB)base_stack)->stksize = fs_size + sizeof(SB);
  458.     }
  459.  
  460.     /* Copy the callers arguments */
  461.     memcpy(base_stack+argofs+sizeof(SB),argaddr,argsiz+hidden);
  462.  
  463.     /* EVALUATE THE FUNCTION */
  464.     lastalloca = iv->allocalist;
  465.     pes = bterp_eval(iv, ft->funcaddr, base_stack, e_stack,
  466.         base_stack+((PSB)base_stack)->stksize);
  467.  
  468.     /* Transfer the return value */
  469. #if SUPPORT_LONG_DOUBLE
  470.     lastval.Ulongdouble = *((long double*)pes);
  471. #else
  472.     lastval.Udouble = *((double*)pes);
  473. #endif
  474.  
  475.     /* Return to callers' stack */
  476.     if(fmods & Fretdbl)
  477.     {
  478.         asm ("fldl %0" :: "g"(lastval.Udouble));
  479.     }
  480.     else if(fmods & Fretflt)
  481.     {
  482.         asm ("flds %0" :: "g"(lastval.Ufloat));
  483.     }
  484.     else if(fmods & Fretldbl)
  485.     {
  486. #if SUPPORT_LONG_DOUBLE
  487.         asm ("fstpt %0" :: "g"(lastval.Udouble));
  488. #else
  489.         asm ("fldl %0" :: "g"(lastval.Udouble));
  490. #endif
  491.     }
  492.     else if(strret)
  493.     {/* return pointer to struct */
  494.         retval.ptr = strret;
  495.         /* GCC needs this */
  496.         memcpy(&retval.p1, strret, MIN(8,strucsiz));    /* 8 bytes of struct */
  497.     }
  498.     else
  499.     {
  500.         retval.ptr = lastval.Upointer;
  501.         retval.p1 = lastval.lng.d[1];
  502.         retval.p2 = lastval.lng.d[2];
  503.     }
  504.     purge_allocas(iv, lastalloca);
  505.     if(fmods & Fnested)
  506.     {
  507. #if 0
  508.         *((char**)pes) -= SZ;
  509. #endif
  510.         ft->fmods &= ~Fthunked;
  511.         free(((PSB)base_stack)->thunkaddr);
  512.     }
  513.     else
  514.     {
  515.         free(base_stack);
  516.     }
  517. }
  518.  
  519. static void *
  520. make_callback_thunk(Piv iv, void *base_stack, Pft ft)
  521. {
  522. char *pth;
  523.  
  524.     if(ft->fmods & Fretstr)
  525.     {
  526.         pth = malloc(sizeof(thunk386S));
  527.         memcpy(pth, thunk386S, sizeof(thunk386S));
  528.     }
  529.     else
  530.     {
  531.         pth = malloc(sizeof(thunk386));
  532.         memcpy(pth, thunk386, sizeof(thunk386));
  533.     }
  534.     *((long*)&pth[4]) = (long)ft;
  535.     *((long*)&pth[9]) = (long)iv;
  536.     *((long*)&pth[14]) = (long)base_stack;
  537.     *((long*)&pth[22]) = (long)_bterp_handle_callbacks;
  538.  
  539.     return pth;
  540. }
  541. static void
  542. ensure_strrets(Piv iv)
  543. {
  544.     if(iv->strretcnt+1 >= iv->slcnt) {
  545.         iv->slcnt += 128;
  546.         iv->struclist = realloc(iv->struclist, iv->slcnt * sizeof(void *));
  547.     }
  548. }
  549. static void
  550. prune_structs(Piv iv)
  551. {
  552.     while(iv->strretcnt > 0)
  553.     {
  554.         free(iv->struclist[--iv->strretcnt]);
  555.     }
  556. }
  557. static int
  558. mover(Piv iv, unsigned char *dp, int opcode, int size, char *src, char *dst)
  559. {
  560. char *s, *d;
  561. int bump;
  562.  
  563.     switch(opcode)
  564.     {
  565.         case S1|D1:
  566.             s = src+(G1(dp)<<2);
  567.             d = dst+(G1(dp+1)<<2);
  568.             bump = 3;
  569.             break;
  570.         case S1|D2:
  571.             s = src+(G1(dp)<<2);
  572.             d = dst+(G2(dp+1)<<2);
  573.             bump = 4;
  574.             break;
  575.         case S1|D3:
  576.             s = src+(G1(dp)<<2);
  577.             d = dst+(G3(dp+1)<<0);
  578.             bump = 5;
  579.             break;
  580.         case S1|D4:
  581.             s = src+(G1(dp)<<2);
  582.             d = (void*)G4(dp+1);
  583.             bump = 6;
  584.             break;
  585.         case S2|D1:
  586.             s = src+(G2(dp)<<2);
  587.             d = dst+G1(dp+2);
  588.             bump = 4;
  589.             break;
  590.         case S2|D2:
  591.             s = src+(G2(dp)<<2);
  592.             d = dst+(G2(dp+2)<<2);
  593.             bump = 5;
  594.             break;
  595.         case S2|D3:
  596.             s = src+(G2(dp)<<2);
  597.             d = dst+(G3(dp+2)<<0);
  598.             bump = 6;
  599.             break;
  600.         case S2|D4:
  601.             s = src+(G2(dp)<<2);
  602.             d = (void*)G4(dp+2);
  603.             bump = 7;
  604.             break;
  605.         case S3|D1:
  606.             s = src+(G3(dp)<<0);
  607.             d = dst+(G1(dp+3)<<2);
  608.             bump = 5;
  609.             break;
  610.         case S3|D2:
  611.             s = src+(G3(dp)<<0);
  612.             d = dst+(G2(dp+3)<<2);
  613.             bump = 6;
  614.             break;
  615.         case S3|D3:
  616.             s = src+(G3(dp)<<0);
  617.             d = dst+(G3(dp+3)<<0);
  618.             bump = 7;
  619.             break;
  620.         case S3|D4:
  621.             s = src+(G3(dp)<<0);
  622.             d = (void*)G4(dp+3);
  623.             bump = 8;
  624.             break;
  625.         case S4|D1:
  626.             s = (void*)G4(dp);
  627.             d = dst+(G1(dp+4)<<2);
  628.             bump = 6;
  629.             break;
  630.         case S4|D2:
  631.             s = (void*)G4(dp);
  632.             d = dst+(G2(dp+4)<<2);
  633.             bump = 7;
  634.             break;
  635.         case S4|D3:
  636.             s = (void*)G4(dp);
  637.             d = dst+(G3(dp+4)<<0);
  638.             bump = 8;
  639.             break;
  640.         case S4|D4:
  641.             s = (void*)G4(dp);
  642.             d = (void*)G4(dp+4);
  643.             bump = 9;
  644.             break;
  645.         default:
  646.             printf("bterp:ERROR: bad opcode for `mover' at pc=%lx\n",
  647.                 ((char*)dp - iv->text_base) - 1);
  648.             longjmp(iv->jb, 1);            
  649.     }
  650.     if(size == B1)
  651.         *((char*)d) = *((char*)s);
  652.     else if(size == B2)
  653.         *((short*)d) = *((short*)s);
  654.     else if(size == B4)
  655.         *((long*)d) = *((long*)s);
  656.     else if(size == B8)
  657.         *((double*)d) = *((double*)s);
  658.     else
  659.         memcpy(d,s,XSZ);
  660.     return bump;
  661. }
  662. static void
  663. load_efunc(Piv iv, Pft ft)
  664. {
  665. void *e_faddr;
  666.     if(!(e_faddr = oxlink_find_bare_func((void*)ft->funcaddr)))
  667.     {/* not in core, load the file */
  668.         if(!(e_faddr = oxlink_load_bare_symb((void*)ft->funcaddr, 1)))
  669.         {
  670.             printf("bterp:ERROR: Can't load function `%s'\n", (char*)ft->funcaddr);
  671.             exit(1);
  672.         }
  673.     }
  674.     ft->funcaddr = (long)e_faddr;
  675.     ft->fmods |= Fthunked;
  676. }
  677. /* MOST OF THESE BUILTINS ARE UNNECESSARY DEMOS */
  678. /* PUT ANYTHING THAT COULD BE CALLED THROUGH A FUNCPTR HERE */
  679. static int
  680. do_builtin(Piv iv, unsigned char code, char **pes)
  681. {/* NOTE: builtins with no args and void return must leave a pseudo ret on stack */
  682. char *es, *oes;
  683.     es = *pes;
  684.     oes = es-SZ;
  685.  
  686.     switch(code)
  687.     {
  688.         case ALLOCA:
  689.         {
  690.         char *abuf = malloc(*((unsigned*)es)+sizeof(void*));
  691.             *((void**)es) = abuf+sizeof(void*);
  692.             *((void**)abuf) = iv->allocalist;
  693.             iv->allocalist = abuf;
  694.             return 1;
  695.         }
  696.         case STRLEN:
  697.         {
  698.             *((unsigned*)es) = strlen(*((const char**)es));
  699.             return 1;
  700.         }
  701.         case STRCPY:
  702.         {
  703.             *((void**)oes) = strcpy(*((char**)oes),*((const char**)es));
  704.             *pes = oes;
  705.             return 1;
  706.         }
  707.         case STRCAT:
  708.         {
  709.             *((void**)oes) = strcat(*((char**)oes),*((const char**)es));
  710.             *pes = oes;
  711.             return 1;
  712.         }
  713.         case MEMCPY:
  714.         {
  715.             *((void**)(oes-SZ)) = memcpy(*((void**)(oes-SZ)),*((const void**)oes),*((unsigned*)es));
  716.             *pes -= 2*SZ;
  717.             return 1;
  718.         }
  719.         case MEMMOVE:
  720.         {
  721.             *((void**)(oes-SZ)) = memmove(*((void**)(oes-SZ)),*((const void**)oes),*((unsigned*)es));
  722.             *pes -= 2*SZ;
  723.             return 1;
  724.         }
  725.         case MEMSET:
  726.         {
  727.             *((void**)(oes-SZ)) = 
  728.                 memset(*((void**)(oes-SZ)),*((int*)oes),*((long*)es));
  729.             *pes -= 2*SZ;
  730.             return 1;
  731.         }
  732.         case BZERO:
  733.         {
  734.             memset(*((void**)oes),0,*((unsigned*)es));
  735.             *pes = oes;
  736.             return 0;
  737.         }
  738.         case DEBUG:
  739.         {
  740.             iv->debug=1;
  741.             printf("DEBUG ON\n");
  742.             fflush(stdout);
  743.             *pes = es+SZ;    /* pseudo ret */
  744.             return 0;
  745.         }
  746.         case NODEBUG:
  747.         {
  748.             iv->debug=0;
  749.             printf("DEBUG OFF\n");
  750.             fflush(stdout);
  751.             *pes = es+SZ;    /* pseudo ret */
  752.             return 0;
  753.         }
  754.         case MALLOC:
  755.         {
  756.             *((void**)es) = malloc(*((unsigned*)es));
  757.             return 1;
  758.         }
  759.         case CALLOC:
  760.         {
  761.             *((void**)oes) = calloc(*((unsigned*)oes),*((unsigned*)es));
  762.             *pes = oes;
  763.             return 1;
  764.         }
  765.         case REALLOC:
  766.         {
  767.             *((void**)oes) = realloc(*((void**)oes),*((unsigned*)es));
  768.             *pes = oes;
  769.             return 1;
  770.         }
  771.     }    
  772.     return 0;
  773. }
  774. static void *
  775. bterp_eval(Piv iv, long pc_offset, void *base_stack, char *es, char *eb)
  776. {
  777. char *dd, *fs;
  778. unsigned char *pc, *np;
  779. char *oes, *nes, *bes;
  780. long first_loc = -100;
  781. long last_loc = 0;
  782.  
  783.   dd = iv->dd;
  784.   fs = base_stack + sizeof(SB);
  785.   pc = iv->text_base + pc_offset;
  786.   bes = es;
  787.  
  788. if(iv->debug) {
  789. printf("FUNCTION ofs=%lx pc=%p bs=%p fs=%p es=%p dd=%p eb=%p\n", 
  790. pc_offset, pc, base_stack, fs, es, dd, eb);
  791. fflush(stdout);
  792. }
  793.   for(;;++pc)
  794.   {
  795.     np = pc+1;
  796.     oes = es-SZ;
  797.     nes = es+SZ;
  798.  
  799. if(iv->debug) {
  800. printf("ofs:%lx op=%x es=%p val=%lx oval=%lx nval=%lx\n",
  801. ((char*)pc) - iv->text_base, *pc, es, 
  802. *((long*)es), *((long*)oes), *((long*)nes));
  803. fflush(stdout);
  804. }
  805. if(es < bes) {
  806. printf("bterp:ERROR: STACK UNDERFLOW ofs:%lx op=%x es=%p val=%lx oval=%lx nval=%lx\n",
  807. ((char*)pc) - iv->text_base, *pc, es, *((long*)es), *((long*)oes), *((long*)nes));
  808. fflush(stdout);
  809. longjmp(iv->jb, (int)es);
  810. }
  811. if(es >= eb) {
  812. printf("bterp:ERROR: STACK OVERFLOW ofs:%lx op=%x es=%p val=%lx oval=%lx nval=%lx\n",
  813. ((char*)pc) - iv->text_base, *pc, es, *((long*)es), *((long*)oes), *((long*)nes));
  814. fflush(stdout);
  815. longjmp(iv->jb, (int)es);
  816. }
  817.     switch(*pc)
  818.     {
  819.         case LOCATE|J1:
  820.         {
  821.             last_loc = ((char*)(pc + GP1(np))) - iv->text_base;
  822.             if(first_loc == -100) first_loc = last_loc;             
  823.             ++pc;
  824.             break;
  825.         }
  826.         case LOCATE|J2:
  827.         {
  828.             last_loc = ((char*)(pc + GP2(np))) - iv->text_base;
  829.             if(first_loc == -100) first_loc = last_loc;             
  830.             pc += 2;
  831.             break;
  832.         }
  833.         case LOCATE|J3:
  834.         {
  835.             last_loc = ((char*)(pc + GP3(np))) - iv->text_base;
  836.             if(first_loc == -100) first_loc = last_loc;             
  837.             pc += 3;
  838.             break;
  839.         }
  840.         case LOCATE|J4:
  841.         {
  842.             last_loc = ((char*)(pc + GP4(np))) - iv->text_base;
  843.             if(first_loc == -100) first_loc = last_loc;             
  844.             pc += 4;
  845.             break;
  846.         }
  847.         case LS|A1|B1:
  848.             LOADSTK1(char);
  849.         case LS|A1|B2:
  850.             LOADSTK1(short);
  851.         case LS|A1|B4:
  852.             LOADSTK1(long);
  853.         case LS|A1|B8:
  854.             LOADSTK1(double);
  855.         case LS|A2|B1:
  856.             LOADSTK2(char);
  857.         case LS|A2|B2:
  858.             LOADSTK2(short);
  859.         case LS|A2|B4:
  860.             LOADSTK2(long);
  861.         case LS|A2|B8:
  862.             LOADSTK2(double);
  863.         case LS|A3|B1:
  864.             LOADSTK3(char);
  865.         case LS|A3|B2:
  866.             LOADSTK3(short);
  867.         case LS|A3|B4:
  868.             LOADSTK3(long);
  869.         case LS|A3|B8:
  870.             LOADSTK3(double);
  871.  
  872.         case NEG|BYTE:
  873.             NEG_ES(char);
  874.         case NEG|SHORT:
  875.             NEG_ES(short);
  876.         case NEG|LONG:
  877.             NEG_ES(long);
  878.         case NEG|UBYTE:
  879.             NEG_ES(unsigned char);
  880.         case NEG|USHORT:
  881.             NEG_ES(unsigned short);
  882.         case NEG|ULONG:
  883.             NEG_ES(unsigned long);
  884.         case NEG|FLOAT:
  885.             NEG_ES(float);
  886.         case NEG|DOUBLE:
  887.             NEG_ES(double);
  888.  
  889.         case LM|A1|B1:
  890.             LOADMEM1(char);
  891.         case LM|A1|B2:
  892.             LOADMEM1(short);
  893.         case LM|A1|B4:
  894.             LOADMEM1(long);
  895.         case LM|A1|B8:
  896.             LOADMEM1(double);
  897.         case LM|A2|B1:
  898.             LOADMEM2(char);
  899.         case LM|A2|B2:
  900.             LOADMEM2(short);
  901.         case LM|A2|B4:
  902.             LOADMEM2(long);
  903.         case LM|A2|B8:
  904.             LOADMEM2(double);
  905.         case LM|A3|B1:
  906.             LOADMEM3(char);
  907.         case LM|A3|B2:
  908.             LOADMEM3(short);
  909.         case LM|A3|B4:
  910.             LOADMEM3(long);
  911.         case LM|A3|B8:
  912.             LOADMEM3(double);
  913.         case LM|A4|B1:
  914.             LOADMEM4(char);
  915.         case LM|A4|B2:
  916.             LOADMEM4(short);
  917.         case LM|A4|B4:
  918.             LOADMEM4(long);
  919.         case LM|A4|B8:
  920.             LOADMEM4(double);
  921.  
  922.         case COMP|B1:
  923.             COMP_ES(char);
  924.         case COMP|B2:
  925.             COMP_ES(short);
  926.         case COMP|B4:
  927.             COMP_ES(long);
  928. #if SUPPORT_LONG_LONG
  929.         case COMP|B8:
  930.             COMP_ES(long long);
  931. #else
  932. #endif
  933.         case JMP|J1:
  934.             pc += GP1(np)-1;
  935.             break;
  936.         case JMP|J2:
  937.             pc += GP2(np)-1;
  938.             break;
  939.         case JMP|J3:
  940.             pc += GP3(np)-1;
  941.             break;
  942.         case JMP|J4:
  943.             pc += GP4(np)-1;
  944.             break;
  945.  
  946.         case LJMPT|J1:
  947.             if(*(es)) pc += GP1(np)-1;
  948.             else {pc += 1; es=oes;}
  949.             break;
  950.         case LJMPT|J2:
  951.             if(*(es)) pc += GP2(np)-1;
  952.             else {pc += 2; es=oes;}
  953.             break;
  954.         case LJMPT|J3:
  955.             if(*(es)) pc += GP3(np)-1;
  956.             else {pc += 3; es=oes;}
  957.             break;
  958.         case LJMPT|J4:
  959.             if(*(es)) pc += GP4(np)-1;
  960.             else {pc += 4; es=oes;}
  961.             break;
  962.  
  963.         case JMPT|J1:
  964.             if(*(es)) pc += GP1(np)-1;
  965.             else pc += 1;
  966.             es = oes;
  967.             break;
  968.         case JMPT|J2:
  969.             if(*(es)) pc += GP2(np)-1;
  970.             else pc += 2;
  971.             es = oes;
  972.             break;
  973.         case JMPT|J3:
  974.             if(*(es)) pc += GP3(np)-1;
  975.             else pc += 3;
  976.             es = oes;
  977.             break;
  978.         case JMPT|J4:
  979.             if(*(es)) pc += GP4(np)-1;
  980.             else pc += 4;
  981.             es = oes;
  982.             break;
  983.  
  984.         case LJMPF|J1:
  985.             if(!*(es)) pc += GP1(np)-1;
  986.             else {pc += 1; es=oes;}
  987.             break;
  988.         case LJMPF|J2:
  989.             if(!*(es)) pc += GP2(np)-1;
  990.             else {pc += 2; es=oes;};
  991.             break;
  992.         case LJMPF|J3:
  993.             if(!*(es)) pc += GP3(np)-1;
  994.             else {pc += 3; es=oes;}
  995.             break;
  996.         case LJMPF|J4:
  997.             if(!*(es)) pc += GP4(np)-1;
  998.             else {pc +=4; es=oes;}
  999.             break;
  1000.  
  1001.         case JMPF|J1:
  1002.             if(!*(es)) pc += GP1(np)-1;
  1003.             else pc += 1;
  1004.             es = oes;
  1005.             break;
  1006.         case JMPF|J2:
  1007.             if(!*(es)) pc += GP2(np)-1;
  1008.             else pc += 2;
  1009.             es = oes;
  1010.             break;
  1011.         case JMPF|J3:
  1012.             if(!*(es)) pc += GP3(np)-1;
  1013.             else pc += 3;
  1014.             es = oes;
  1015.             break;
  1016.         case JMPF|J4:
  1017.             if(!*(es)) pc += GP4(np)-1;
  1018.             else pc +=4;
  1019.             es = oes;
  1020.             break;
  1021.  
  1022.         case NOT|B1:
  1023.             NOT_ES(char);
  1024.         case NOT|B2:
  1025.             NOT_ES(short);
  1026.         case NOT|B4:    /* also FLOAT */
  1027.             NOT_ES(long);
  1028.         case NOT|B8:    /* also DOUBLE */
  1029. #if SUPPORT_LONG_LONG
  1030.             NOT_ES(long long);
  1031. #else
  1032.             NOT_ES1;
  1033. #endif
  1034.         case SS|A1|B1:
  1035.             STORSTK1(char);
  1036.         case SS|A1|B2:
  1037.             STORSTK1(short);
  1038.         case SS|A1|B4:
  1039.             STORSTK1(long);
  1040.         case SS|A1|B8:
  1041.             STORSTK1(double);
  1042.         case SS|A2|B1:
  1043.             STORSTK2(char);
  1044.         case SS|A2|B2:
  1045.             STORSTK2(short);
  1046.         case SS|A2|B4:
  1047.             STORSTK2(long);
  1048.         case SS|A2|B8:
  1049.             STORSTK2(double);
  1050.         case SS|A3|B1:
  1051.             STORSTK3(char);
  1052.         case SS|A3|B2:
  1053.             STORSTK3(short);
  1054.         case SS|A3|B4:
  1055.             STORSTK3(long);
  1056.         case SS|A3|B8:
  1057.             STORSTK3(double);
  1058.  
  1059.         case TRUTHOF|B2:
  1060.             TRUTH_ES(short);
  1061.         case TRUTHOF|B4:        /* also FLOAT */
  1062.             TRUTH_ES(long);
  1063.         case TRUTHOF|B8:        /* also DOUBLE */
  1064. #if SUPPORT_LONG_LONG
  1065.             TRUTH_ES(long long);
  1066. #else
  1067.             TRUTH_ES1;
  1068. #endif
  1069.         case CVT:
  1070.         {
  1071.             ++pc;
  1072.             ++np;
  1073.             switch(*pc)
  1074.             {
  1075.                 case SRC(BYTE)|SHORT:
  1076.                     *((short*)es) = *((char*)es);
  1077.                     break;
  1078.                 case SRC(BYTE)|LONG:
  1079.                     *((long*)es) = *((char*)es);
  1080.                     break;
  1081.                 case SRC(BYTE)|USHORT:
  1082.                     *((unsigned short*)es) = *((char*)es);
  1083.                     break;
  1084.                 case SRC(BYTE)|ULONG:
  1085.                     *((unsigned long*)es) = *((char*)es);
  1086.                     break;
  1087.                 case SRC(BYTE)|FLOAT:
  1088.                     *((float*)es) = *((char*)es);
  1089.                     break;
  1090.                 case SRC(BYTE)|DOUBLE:
  1091.                     *((double*)es) = *((char*)es);
  1092.                     break;
  1093. #if SUPPORT_LONG_LONG
  1094.                 case SRC(BYTE)|CLONGLONG:
  1095.                     *((long long*)es) = *((char*)es);
  1096.                     break;
  1097.                 case SRC(BYTE)|CULONGLONG:
  1098.                     *((unsigned long long*)es) = *((char*)es);
  1099.                     break;
  1100. #endif
  1101. #if SUPPORT_LONG_DOUBLE
  1102.                 case SRC(BYTE)|CLONGDOUBLE:
  1103.                     *((long double*)es) = *((char*)es);
  1104.                     break;
  1105. #endif
  1106.                 case SRC(SHORT)|LONG:
  1107.                     *((long*)es) = *((short*)es);
  1108.                     break;
  1109.                 case SRC(SHORT)|ULONG:
  1110.                     *((unsigned long*)es) = *((short*)es);
  1111.                     break;
  1112.                 case SRC(SHORT)|FLOAT:
  1113.                     *((float*)es) = *((short*)es);
  1114.                     break;
  1115.                 case SRC(SHORT)|DOUBLE:
  1116.                     *((double*)es) = *((short*)es);
  1117.                     break;
  1118. #if SUPPORT_LONG_LONG
  1119.                 case SRC(SHORT)|CLONGLONG:
  1120.                     *((long long*)es) = *((short*)es);
  1121.                     break;
  1122.                 case SRC(SHORT)|CULONGLONG:
  1123.                     *((unsigned long long*)es) = *((short*)es);
  1124.                     break;
  1125. #endif
  1126. #if SUPPORT_LONG_DOUBLE
  1127.                 case SRC(SHORT)|CLONGDOUBLE:
  1128.                     *((long double*)es) = *((short*)es);
  1129.                     break;
  1130. #endif
  1131.                 case SRC(LONG)|FLOAT:
  1132.                     *((float*)es) = *((long*)es);
  1133.                     break;
  1134.                 case SRC(LONG)|DOUBLE:
  1135.                     *((double*)es) = *((long*)es);
  1136.                     break;
  1137. #if SUPPORT_LONG_LONG
  1138.                 case SRC(LONG)|CLONGLONG:
  1139.                     *((long long*)es) = *((long*)es);
  1140.                     break;
  1141.                 case SRC(LONG)|CULONGLONG:
  1142.                     *((unsigned long long*)es) = *((long*)es);
  1143.                     break;
  1144. #endif
  1145. #if SUPPORT_LONG_DOUBLE
  1146.                 case SRC(LONG)|CLONGDOUBLE:
  1147.                     *((long double*)es) = *((long*)es);
  1148.                     break;
  1149. #endif
  1150.                 case SRC(UBYTE)|SHORT:
  1151.                     *((short*)es) = *((unsigned char*)es);
  1152.                     break;
  1153.                 case SRC(UBYTE)|LONG:
  1154.                     *((long*)es) = *((unsigned char*)es);
  1155.                     break;
  1156.                 case SRC(UBYTE)|USHORT:
  1157.                     *((unsigned short*)es) = *((unsigned char*)es);
  1158.                     break;
  1159.                 case SRC(UBYTE)|ULONG:
  1160.                     *((unsigned long*)es) = *((unsigned char*)es);
  1161.                     break;
  1162.                 case SRC(UBYTE)|FLOAT:
  1163.                     *((float*)es) = *((unsigned char*)es);
  1164.                     break;
  1165.                 case SRC(UBYTE)|DOUBLE:
  1166.                     *((double*)es) = *((unsigned char*)es);
  1167.                     break;
  1168. #if SUPPORT_LONG_LONG
  1169.                 case SRC(UBYTE)|CLONGLONG:
  1170.                     *((long long*)es) = *((unsigned char*)es);
  1171.                     break;
  1172.                 case SRC(UBYTE)|CULONGLONG:
  1173.                     *((unsigned long long*)es) = *((unsigned char*)es);
  1174.                     break;
  1175. #endif
  1176. #if SUPPORT_LONG_DOUBLE
  1177.                 case SRC(UBYTE)|CLONGDOUBLE:
  1178.                     *((long double*)es) = *((unsigned char*)es);
  1179.                     break;
  1180. #endif
  1181.                 case SRC(USHORT)|LONG:
  1182.                     *((long*)es) = *((unsigned short*)es);
  1183.                     break;
  1184.                 case SRC(USHORT)|ULONG:
  1185.                     *((unsigned long*)es) = *((unsigned short*)es);
  1186.                     break;
  1187.                 case SRC(USHORT)|FLOAT:
  1188.                     *((float*)es) = *((unsigned short*)es);
  1189.                     break;
  1190.                 case SRC(USHORT)|DOUBLE:
  1191.                     *((double*)es) = *((unsigned short*)es);
  1192.                     break;
  1193. #if SUPPORT_LONG_LONG
  1194.                 case SRC(USHORT)|CLONGLONG:
  1195.                     *((long long*)es) = *((unsigned short*)es);
  1196.                     break;
  1197.                 case SRC(USHORT)|CULONGLONG:
  1198.                     *((unsigned long long*)es) = *((unsigned short*)es);
  1199.                     break;
  1200. #endif
  1201. #if SUPPORT_LONG_DOUBLE
  1202.                 case SRC(USHORT)|CLONGDOUBLE:
  1203.                     *((long double*)es) = *((unsigned short*)es);
  1204.                     break;
  1205. #endif
  1206.                 case SRC(ULONG)|FLOAT:
  1207.                     *((float*)es) = *((unsigned long*)es);
  1208.                     break;
  1209.                 case SRC(ULONG)|DOUBLE:
  1210.                     *((double*)es) = *((unsigned long*)es);
  1211.                     break;
  1212. #if SUPPORT_LONG_LONG
  1213.                 case SRC(ULONG)|CLONGLONG:
  1214.                     *((long long*)es) = *((unsigned long*)es);
  1215.                     break;
  1216.                 case SRC(ULONG)|CULONGLONG:
  1217.                     *((unsigned long long*)es) = *((unsigned long*)es);
  1218.                     break;
  1219. #endif
  1220. #if SUPPORT_LONG_DOUBLE
  1221.                 case SRC(ULONG)|CLONGDOUBLE:
  1222.                     *((long double*)es) = *((unsigned long*)es);
  1223.                     break;
  1224. #endif
  1225.                 case SRC(FLOAT)|BYTE:
  1226.                     *((char*)es) = *((float*)es);
  1227.                     break;
  1228.                 case SRC(FLOAT)|SHORT:
  1229.                     *((short*)es) = *((float*)es);
  1230.                     break;
  1231.                 case SRC(FLOAT)|LONG:
  1232.                     *((long*)es) = *((float*)es);
  1233.                     break;
  1234.                 case SRC(FLOAT)|UBYTE:
  1235.                     *((unsigned char*)es) = *((float*)es);
  1236.                     break;
  1237.                 case SRC(FLOAT)|USHORT:
  1238.                     *((unsigned short*)es) = *((float*)es);
  1239.                     break;
  1240.                 case SRC(FLOAT)|ULONG:
  1241.                     *((unsigned long*)es) = *((float*)es);
  1242.                     break;
  1243.                 case SRC(FLOAT)|DOUBLE:
  1244.                     *((double*)es) = *((float*)es);
  1245.                     break;
  1246. #if SUPPORT_LONG_LONG
  1247.                 case SRC(FLOAT)|CLONGLONG:
  1248.                     *((long long*)es) = *((float*)es);
  1249.                     break;
  1250.                 case SRC(FLOAT)|CULONGLONG:
  1251.                     *((unsigned long long*)es) = *((float*)es);
  1252.                     break;
  1253. #endif
  1254. #if SUPPORT_LONG_DOUBLE
  1255.                 case SRC(FLOAT)|CLONGDOUBLE:
  1256.                     *((long double*)es) = *((float*)es);
  1257.                     break;
  1258. #endif
  1259.                 case SRC(DOUBLE)|BYTE:
  1260.                     *((char*)es) = *((double*)es);
  1261.                     break;
  1262.                 case SRC(DOUBLE)|SHORT:
  1263.                     *((short*)es) = *((double*)es);
  1264.                     break;
  1265.                 case SRC(DOUBLE)|LONG:
  1266.                     *((long*)es) = *((double*)es);
  1267.                     break;
  1268.                 case SRC(DOUBLE)|UBYTE:
  1269.                     *((unsigned char*)es) = *((double*)es);
  1270.                     break;
  1271.                 case SRC(DOUBLE)|USHORT:
  1272.                     *((unsigned short*)es) = *((double*)es);
  1273.                     break;
  1274.                 case SRC(DOUBLE)|ULONG:
  1275.                     *((unsigned long*)es) = *((double*)es);
  1276.                     break;
  1277.                 case SRC(DOUBLE)|FLOAT:
  1278.                     *((float*)es) = *((double*)es);
  1279.                     break;
  1280. #if SUPPORT_LONG_LONG
  1281.                 case SRC(DOUBLE)|CLONGLONG:
  1282.                     *((long long*)es) = *((double*)es);
  1283.                     break;
  1284.                 case SRC(DOUBLE)|CULONGLONG:
  1285.                     *((unsigned long long*)es) = *((double*)es);
  1286.                     break;
  1287. #endif
  1288. #if SUPPORT_LONG_DOUBLE
  1289.                 case SRC(DOUBLE)|CLONGDOUBLE:
  1290.                     *((long double*)es) = *((double*)es);
  1291.                     break;
  1292. #endif
  1293. #if SUPPORT_LONG_LONG
  1294.                 case SRC(CLONGLONG)|FLOAT:
  1295.                     *((float*)es) = *((long long*)es);
  1296.                     break;
  1297.                 case SRC(CLONGLONG)|DOUBLE:
  1298.                     *((double*)es) = *((long long*)es);
  1299.                     break;
  1300. #if SUPPORT_LONG_DOUBLE
  1301.                 case SRC(CLONGLONG)|CLONGDOUBLE:
  1302.                     *((long double*)es) = *((long long*)es);
  1303.                     break;
  1304. #endif
  1305.                 case SRC(CULONGLONG)|FLOAT:
  1306.                     *((float*)es) = *((unsigned long long*)es);
  1307.                     break;
  1308.                 case SRC(CULONGLONG)|DOUBLE:
  1309.                     *((double*)es) = *((unsigned long long*)es);
  1310.                     break;
  1311. #if SUPPORT_LONG_DOUBLE
  1312.                 case SRC(CULONGLONG)|CLONGDOUBLE:
  1313.                     *((long double*)es) = *((unsigned long long*)es);
  1314.                     break;
  1315. #endif
  1316. #endif
  1317. #if SUPPORT_LONG_DOUBLE
  1318.                 case SRC(CLONGDOUBLE)|BYTE:
  1319.                     *((char*)es) = *((long double*)es);
  1320.                     break;
  1321.                 case SRC(CLONGDOUBLE)|SHORT:
  1322.                     *((short*)es) = *((long double*)es);
  1323.                     break;
  1324.                 case SRC(CLONGDOUBLE)|LONG:
  1325.                     *((long*)es) = *((long double*)es);
  1326.                     break;
  1327.                 case SRC(CLONGDOUBLE)|UBYTE:
  1328.                     *((unsigned char*)es) = *((long double*)es);
  1329.                     break;
  1330.                 case SRC(CLONGDOUBLE)|USHORT:
  1331.                     *((unsigned short*)es) = *((long double*)es);
  1332.                     break;
  1333.                 case SRC(CLONGDOUBLE)|ULONG:
  1334.                     *((unsigned long*)es) = *((long double*)es);
  1335.                     break;
  1336.                 case SRC(CLONGDOUBLE)|FLOAT:
  1337.                     *((float*)es) = *((long double*)es);
  1338.                     break;
  1339.                 case SRC(CLONGDOUBLE)|DOUBLE:
  1340.                     *((double*)es) = *((long double*)es);
  1341.                     break;
  1342. #if SUPPORT_LONG_LONG
  1343.                 case SRC(CLONGDOUBLE)|CLONGLONG:
  1344.                     *((long long*)es) = *((long double*)es);
  1345.                     break;
  1346.                 case SRC(CLONGDOUBLE)|CULONGLONG:
  1347.                     *((unsigned long long*)es) = *((long double*)es);
  1348.                     break;
  1349. #endif
  1350. #endif
  1351.             }
  1352.             break;
  1353.         }
  1354.         case IMMED:
  1355.         {
  1356.             ++pc;
  1357.             ++np;
  1358.             switch(*pc)
  1359.             {
  1360.  
  1361.                 case SMI|A1|B1:
  1362.                     STORMEMI1(char);
  1363.                 case SMI|A1|B2:
  1364.                     STORMEMI1(short);
  1365.                 case SMI|A1|B4:
  1366.                     STORMEMI1(long);
  1367.                 case SMI|A1|B8:
  1368.                     STORMEMI1(double);
  1369.                 case SMI|A2|B1:
  1370.                     STORMEMI2(char);
  1371.                 case SMI|A2|B2:
  1372.                     STORMEMI2(short);
  1373.                 case SMI|A2|B4:
  1374.                     STORMEMI2(long);
  1375.                 case SMI|A2|B8:
  1376.                     STORMEMI2(double);
  1377.                 case SMI|A3|B1:
  1378.                     STORMEMI3(char);
  1379.                 case SMI|A3|B2:
  1380.                     STORMEMI3(short);
  1381.                 case SMI|A3|B4:
  1382.                     STORMEMI3(long);
  1383.                 case SMI|A3|B8:
  1384.                     STORMEMI3(double);
  1385.                 case SMI|A4|B1:
  1386.                     STORMEMI4(char);
  1387.                 case SMI|A4|B2:
  1388.                     STORMEMI4(short);
  1389.                 case SMI|A4|B4:
  1390.                     STORMEMI4(long);
  1391.                 case SMI|A4|B8:
  1392.                     STORMEMI4(double);
  1393.  
  1394.                 case SSI|A1|B1:
  1395.                     STORSTKI1(char);
  1396.                 case SSI|A1|B2:
  1397.                     STORSTKI1(short);
  1398.                 case SSI|A1|B4:
  1399.                     STORSTKI1(long);
  1400.                 case SSI|A1|B8:
  1401.                     STORSTKI1(double);
  1402.                 case SSI|A2|B1:
  1403.                     STORSTKI2(char);
  1404.                 case SSI|A2|B2:
  1405.                     STORSTKI2(short);
  1406.                 case SSI|A2|B4:
  1407.                     STORSTKI2(long);
  1408.                 case SSI|A2|B8:
  1409.                     STORSTKI2(double);
  1410.                 case SSI|A3|B1:
  1411.                     STORSTKI3(char);
  1412.                 case SSI|A3|B2:
  1413.                     STORSTKI3(short);
  1414.                 case SSI|A3|B4:
  1415.                     STORSTKI3(long);
  1416.                 case SSI|A3|B8:
  1417.                     STORSTKI3(double);
  1418.  
  1419.                 case MODI|BYTE:
  1420.                     MODI_ES(char);
  1421.                 case MODI|SHORT:
  1422.                     MODI_ES(short);
  1423.                 case MODI|LONG:
  1424.                     MODI_ES(long);
  1425.                 case MODI|UBYTE:
  1426.                     MODI_ES(unsigned char);
  1427.                 case MODI|USHORT:
  1428.                     MODI_ES(unsigned short);
  1429.                 case MODI|ULONG:
  1430.                     MODI_ES(unsigned long);
  1431.  
  1432.                 case DEREF|BYTE:
  1433.                     DEREF_ES(char);
  1434.                 case DEREF|SHORT:
  1435.                     DEREF_ES(short);
  1436.                 case DEREF|LONG:
  1437.                     DEREF_ES(long);
  1438.                 case DEREF|UBYTE:
  1439.                     UDEREF_ES(unsigned char);
  1440.                 case DEREF|USHORT:
  1441.                     UDEREF_ES(unsigned short);
  1442.                 case DEREF|ULONG:
  1443.                     UDEREF_ES(unsigned long);
  1444.                 case DEREF|FLOAT:
  1445.                     FDEREF_ES(float);
  1446.                 case DEREF|DOUBLE:
  1447.                     FDEREF_ES(double);
  1448.  
  1449.                 case DEREF1|BYTE:
  1450.                     DEREF1_ES(char);
  1451.                 case DEREF1|SHORT:
  1452.                     DEREF1_ES(short);
  1453.                 case DEREF1|LONG:
  1454.                     DEREF1_ES(long);
  1455.                 case DEREF1|UBYTE:
  1456.                     UDEREF1_ES(unsigned char);
  1457.                 case DEREF1|USHORT:
  1458.                     UDEREF1_ES(unsigned short);
  1459.                 case DEREF1|ULONG:
  1460.                     UDEREF1_ES(unsigned long);
  1461.                 case DEREF1|FLOAT:
  1462.                     FDEREF1_ES(float);
  1463.                 case DEREF1|DOUBLE:
  1464.                     FDEREF1_ES(double);
  1465.             }
  1466.             break;
  1467.         }
  1468.         case LI|B1:
  1469.             LOADI1();
  1470.         case LI|B2:
  1471.             LOADI2();
  1472.         case LI|B4:
  1473.             LOADI4();
  1474.         case LI|B8:
  1475.             LOADI8();
  1476.         case LAI|D1:
  1477.             LOADADDRI1();
  1478.         case LAI|D2:
  1479.             LOADADDRI2();
  1480.         case LAI|D3:
  1481.             LOADADDRI3();
  1482.         case LAI|D4:
  1483.             LOADADDRI4();
  1484.  
  1485.         case LUI|B1:
  1486.             LOADUI1();
  1487.         case LUI|B2:
  1488.             LOADUI2();
  1489.         case LUI|B4:
  1490.             LOADUI4();
  1491.         case LUI|B8:
  1492.             LOADI8();
  1493.  
  1494.         case SM|A1|B1:
  1495.             STORMEM1(char);
  1496.         case SM|A1|B2:
  1497.             STORMEM1(short);
  1498.         case SM|A1|B4:
  1499.             STORMEM1(long);
  1500.         case SM|A1|B8:
  1501.             STORMEM1(double);
  1502.         case SM|A2|B1:
  1503.             STORMEM2(char);
  1504.         case SM|A2|B2:
  1505.             STORMEM2(short);
  1506.         case SM|A2|B4:
  1507.             STORMEM2(long);
  1508.         case SM|A2|B8:
  1509.             STORMEM2(double);
  1510.         case SM|A3|B1:
  1511.             STORMEM3(char);
  1512.         case SM|A3|B2:
  1513.             STORMEM3(short);
  1514.         case SM|A3|B4:
  1515.             STORMEM3(long);
  1516.         case SM|A3|B8:
  1517.             STORMEM3(double);
  1518.         case SM|A4|B1:
  1519.             STORMEM4(char);
  1520.         case SM|A4|B2:
  1521.             STORMEM4(short);
  1522.         case SM|A4|B4:
  1523.             STORMEM4(long);
  1524.         case SM|A4|B8:
  1525.             STORMEM4(double);
  1526.  
  1527.  
  1528.         case ADD|BYTE:
  1529.             ADD_ES(char);
  1530.         case ADD|SHORT:
  1531.             ADD_ES(short);
  1532.         case ADD|LONG:
  1533.             ADD_ES(long);
  1534.         case ADD|UBYTE:
  1535.             ADD_ES(unsigned char);
  1536.         case ADD|USHORT:
  1537.             ADD_ES(unsigned short);
  1538.         case ADD|ULONG:
  1539.             ADD_ES(unsigned long);
  1540.         case ADD|FLOAT:
  1541.             ADD_ES(float);
  1542.         case ADD|DOUBLE:
  1543.             ADD_ES(double);
  1544.  
  1545.         case SUB|BYTE:
  1546.             SUB_ES(char);
  1547.         case SUB|SHORT:
  1548.             SUB_ES(short);
  1549.         case SUB|LONG:
  1550.             SUB_ES(long);
  1551.         case SUB|UBYTE:
  1552.             SUB_ES(unsigned char);
  1553.         case SUB|USHORT:
  1554.             SUB_ES(unsigned short);
  1555.         case SUB|ULONG:
  1556.             SUB_ES(unsigned long);
  1557.         case SUB|FLOAT:
  1558.             SUB_ES(float);
  1559.         case SUB|DOUBLE:
  1560.             SUB_ES(double);
  1561.  
  1562.         case MUL|BYTE:
  1563.             MUL_ES(char);
  1564.         case MUL|SHORT:
  1565.             MUL_ES(short);
  1566.         case MUL|LONG:
  1567.             MUL_ES(long);
  1568.         case MUL|UBYTE:
  1569.             MUL_ES(unsigned char);
  1570.         case MUL|USHORT:
  1571.             MUL_ES(unsigned short);
  1572.         case MUL|ULONG:
  1573.             MUL_ES(unsigned long);
  1574.         case MUL|FLOAT:
  1575.             MUL_ES(float);
  1576.         case MUL|DOUBLE:
  1577.             MUL_ES(double);
  1578.  
  1579.         case DIV|BYTE:
  1580.             DIV_ES(char);
  1581.         case DIV|SHORT:
  1582.             DIV_ES(short);
  1583.         case DIV|LONG:
  1584.             DIV_ES(long);
  1585.         case DIV|UBYTE:
  1586.             DIV_ES(unsigned char);
  1587.         case DIV|USHORT:
  1588.             DIV_ES(unsigned short);
  1589.         case DIV|ULONG:
  1590.             DIV_ES(unsigned long);
  1591.         case DIV|FLOAT:
  1592.             DIV_ES(float);
  1593.         case DIV|DOUBLE:
  1594.             DIV_ES(double);
  1595.  
  1596.         case OR|B1:
  1597.             OR_ES(unsigned char);
  1598.         case OR|B2:
  1599.             OR_ES(unsigned short);
  1600.         case OR|B4:
  1601.             OR_ES(unsigned long);
  1602.  
  1603.         case XOR|B1:
  1604.             XOR_ES(unsigned char);
  1605.         case XOR|B2:
  1606.             XOR_ES(unsigned short);
  1607.         case XOR|B4:
  1608.             XOR_ES(unsigned long);
  1609.  
  1610.         case AND|B1:
  1611.             AND_ES(unsigned char);
  1612.         case AND|B2:
  1613.             AND_ES(unsigned short);
  1614.         case AND|B4:
  1615.             AND_ES(unsigned long);
  1616.  
  1617. #if SUPPORT_LONG_LONG
  1618.         case OR|B8:
  1619.             OR_ES(unsigned long long);
  1620.         case AND|B8:
  1621.             AND_ES(unsigned long long);
  1622.         case XOR|B8:
  1623.             XOR_ES(unsigned long long);
  1624. #else
  1625. #endif
  1626.  
  1627.         case MOD|BYTE:
  1628.             MOD_ES(char);
  1629.         case MOD|SHORT:
  1630.             MOD_ES(short);
  1631.         case MOD|LONG:
  1632.             MOD_ES(long);
  1633.         case MOD|UBYTE:
  1634.             MOD_ES(unsigned char);
  1635.         case MOD|USHORT:
  1636.             MOD_ES(unsigned short);
  1637.         case MOD|ULONG:
  1638.             MOD_ES(unsigned long);
  1639.  
  1640.         case XTD:
  1641.         {
  1642.             ++pc;
  1643.             ++np;
  1644.             switch(*pc)
  1645.             {
  1646.                 case LSH|B1:
  1647.                     LSH_ES(char);
  1648.                 case LSH|B2:
  1649.                     LSH_ES(short);
  1650.                 case LSH|B4:
  1651.                     LSH_ES(long);
  1652.                 case LSH|B8:
  1653.                     LSH_ES(long long);
  1654.  
  1655.                 case LSHI|B1:
  1656.                     LSHI_ES(char);
  1657.                 case LSHI|B2:
  1658.                     LSHI_ES(short);
  1659.                 case LSHI|B4:
  1660.                     LSHI_ES(long);
  1661.                 case LSHI|B8:
  1662.                     LSHI_ES(long long);
  1663.             
  1664.                 case RSH|BYTE:
  1665.                     RSH_ES(char);
  1666.                 case RSH|SHORT:
  1667.                     RSH_ES(short);
  1668.                 case RSH|LONG:
  1669.                     RSH_ES(long);
  1670.                 case RSH|UBYTE:
  1671.                     RSH_ES(unsigned char);
  1672.                 case RSH|USHORT:
  1673.                     RSH_ES(unsigned short);
  1674.                 case RSH|ULONG:
  1675.                     RSH_ES(unsigned long);
  1676.  
  1677.                 case RSHI|BYTE:
  1678.                     RSHI_ES(char);
  1679.                 case RSHI|SHORT:
  1680.                     RSHI_ES(short);
  1681.                 case RSHI|LONG:
  1682.                     RSHI_ES(long);
  1683.                 case RSHI|UBYTE:
  1684.                     RSHI_ES(unsigned char);
  1685.                 case RSHI|USHORT:
  1686.                     RSHI_ES(unsigned short);
  1687.                 case RSHI|ULONG:
  1688.                     RSHI_ES(unsigned long);
  1689.  
  1690.                 case BUILTIN:
  1691.                 {
  1692.                     ++pc;
  1693.                     ++np;
  1694.                     switch(*pc)
  1695.                     {/* THESE BUILTINS CANNOT BE CALLED THROUGH A FUNCPTR */
  1696.                         case SETJMP:
  1697.                         {
  1698.                         long *jb;
  1699.  
  1700.                             jb = *((void**)es);
  1701.                             *((long*)es) = 0;
  1702.     
  1703.                             jb[0] = (long)iv->allocalist;
  1704.                             jb[1] = (long)pc;
  1705.                             if((jb = (long*)setjmp(((void*)&jb[4]))))
  1706.                             {
  1707.                             void *bs,*qs;
  1708.                                 pc = (void*)jb[1];
  1709.                                 *((long*)es) = jb[2];            
  1710.                                 bs = (void*)jb[3];
  1711.                                 while(bs != base_stack)
  1712.                                 {
  1713.                                     qs = ((PSB)bs)->backlink;
  1714.                                     free(bs);
  1715.                                     bs = qs;
  1716.                                 }
  1717.                                 purge_allocas(iv, (void*)jb[0]);
  1718.                                 prune_structs(iv);
  1719.                             }
  1720.                             break;
  1721.                         }
  1722.                         case LONGJMP:
  1723.                         {
  1724.                         long *jb;
  1725.  
  1726.                             jb = *((void**)oes);
  1727.                             jb[2] = *((long*)es);
  1728.                             jb[3] = (long)base_stack;
  1729.                             longjmp(((void*)&jb[4]), (long)jb);
  1730.                             break;
  1731.                         }
  1732.                         case ABORT:
  1733.                             printf("bterp: user program called abort.\n");
  1734.                         case EXIT:
  1735.                         {
  1736.                         void *bs, *qs;
  1737.                             bs = base_stack;
  1738.                             while(bs != iv->base_stack)
  1739.                             {
  1740.                                 qs = ((PSB)bs)->backlink;
  1741.                                 free(bs);
  1742.                                 bs = qs;
  1743.                             }
  1744.                             purge_allocas(iv, 0);
  1745.                             longjmp(iv->jb, (int)es);
  1746.                             break;
  1747.                         }
  1748.                         default:
  1749.                             do_builtin(iv, *pc, &es);
  1750.                             break;
  1751.                     }
  1752.                     break;
  1753.                 } /* END: XTD BUILTIN */
  1754.                 case CLRDAT:
  1755.                 {
  1756.                     memset(*((void**)oes), 0, *((long*)es));
  1757.                     es -= 2*SZ;
  1758.                     break;
  1759.                 }
  1760.                 case SWITCH:
  1761.                 {
  1762.                 unsigned long key[2];
  1763.                 unsigned char **result;
  1764.  
  1765.                     key[0] = *((unsigned short*)np)<<11;
  1766.                     key[1] = *((long*)es);
  1767.                     if(findswitch(iv, key, &result))
  1768.                     {
  1769.                          pc = *result - 1;    
  1770.                     }
  1771.                     else
  1772.                     {
  1773.                         pc += 2;
  1774.                     }
  1775.                     es = oes;
  1776.                     break;
  1777.                 }
  1778.                 case CALLSETUP:
  1779.                 {
  1780.                 PCB cb = (PCB)es;
  1781.                 Pft ft = cb->loc;
  1782.                 int hidden;
  1783.                 long stksiz, maxes;
  1784.                 long argsiz, strucsiz;
  1785.                 int flags = 0;
  1786.                     if(ft->fmods & Fbuiltin)
  1787.                     {/* This only happens if the programmer uses a function
  1788.                         pointer which points to a builtin function. */
  1789.                         flags = 0x80;
  1790.                     }
  1791.                     cb->argsiz = argsiz = G4(np);
  1792.                 
  1793.                     if((hidden = ft->fmods & Fretstr))
  1794.                     {/* function returning a structure */
  1795.                         strucsiz = ft->retsiz<<2;
  1796.                     }    
  1797.                     stksiz = ft->stksiz<<2;
  1798.                     maxes = ft->maxes;
  1799.  
  1800.                     if(ft->fmods & Fnested)
  1801.                     {/* Calling nested function */
  1802.                         cb->argofs = (ft->stkbeg+(stksiz-(ft->argsiz<<2)-hidden)) >> 2;
  1803.                         if(ft->funcaddr >= first_loc && ft->funcaddr <= last_loc)
  1804.                         {/* call from enclosing function */
  1805.                             cb->base_stack = base_stack;
  1806.                             cb->es = es;
  1807.                             cb->flags = 0x10 + hidden;
  1808.                         }
  1809.                         else
  1810.                         {/* callback from another function */
  1811.                         PSB prev = (PSB)(fs - sizeof(SB));
  1812.                         long floc = prev->first_loc;
  1813.                         long lloc = prev->last_loc;
  1814.  
  1815.                           while((prev = prev->backlink))
  1816.                           {
  1817.                             if(        ft->funcaddr >= floc
  1818.                                 &&    ft->funcaddr <= lloc)
  1819.                             {/* This is the container of the nested func */
  1820.                              cb->base_stack = (char*)prev;
  1821.                              cb->es = prev->cbes;
  1822.                              break;
  1823.                             }
  1824.                             floc = prev->first_loc;
  1825.                             lloc = prev->last_loc;
  1826.                           }
  1827.                           cb->flags = 0x20 + hidden;
  1828.                         }
  1829.                     }
  1830.                     else if(ft->fmods & Fextern)
  1831.                     {/* Calling external function */
  1832.                         /* Dynamic link it */
  1833.                         if(!(ft->fmods & Fthunked))
  1834.                             load_efunc(iv, ft);
  1835.  
  1836.                         cb->base_stack = calloc(1, sizeof(SB)+argsiz+hidden);
  1837.                         cb->argsiz = argsiz+hidden;
  1838.                         cb->argofs = 0; 
  1839.                         cb->flags = 0x40 + hidden;
  1840.                     }
  1841.                     else
  1842.                     {/* Calling interpreted function */
  1843.                       if(flags & 0x80)
  1844.                       {
  1845.                         cb->flags = flags;
  1846.                         cb->es = cb->base_stack = calloc(1, 128);
  1847.                       }
  1848.                       else
  1849.                       {
  1850.                       long es_beg;
  1851.                       long fs_size;
  1852.                       PSB sp;
  1853.                         es_beg = stksiz+hidden+argsiz;
  1854.                         fs_size = es_beg + ((maxes+6)*SZ);
  1855.                         cb->base_stack = calloc(1, fs_size+sizeof(SB));
  1856.                         sp = (PSB)cb->base_stack;
  1857.                         cb->es = cb->base_stack + sizeof(SB) + es_beg;
  1858.                         cb->argofs = stksiz >> 2;
  1859.                         cb->flags = flags + hidden;                        
  1860.                         sp->first_loc = first_loc;
  1861.                         sp->last_loc = last_loc;
  1862.                         sp->backlink = base_stack;
  1863.                         sp->stksize = fs_size+sizeof(SB);
  1864.                       }
  1865.                      }
  1866.                     if(hidden)
  1867.                     {/* function returning a structure */
  1868.                     void *strucptr = malloc(strucsiz);
  1869.         *((void**)(cb->base_stack+sizeof(SB)+(cb->argofs<<2))) = strucptr;
  1870.                         ensure_strrets(iv);
  1871.                         iv->struclist[iv->strretcnt++] = strucptr;
  1872.                     }
  1873.                     pc += 4;
  1874.                     break;
  1875.                 }
  1876.                 case RETSTRUCT:
  1877.                 {
  1878.                 long size = G2(np)<<2;
  1879.                 long offset = G2(np+2)<<2;
  1880.                 void *dst;
  1881.  
  1882.                     dst = fs + offset;
  1883.                     dst = *((void**)dst);
  1884.                     memcpy(dst, *((void**)es), size);
  1885. if(iv->debug) {
  1886. printf("RETSTRUCT ofs=%lx es=%p val=0x%lx\n", pc_offset, es, *((long*)es));
  1887. fflush(stdout);
  1888. }
  1889.                     return es;
  1890.                 }
  1891.                 case PRUNESTRUCT:
  1892.                 {
  1893.                     prune_structs(iv);
  1894.                     break;
  1895.                 }
  1896.                 case GETBITFIELD:
  1897.                 {
  1898.                     if(pc[1] + pc[2] <= 32)
  1899.                     {
  1900.                         *((long*)es) >>= pc[1];
  1901.                         *((long*)es) &= bfields[pc[2]];
  1902.                         if(pc[3])
  1903.                         {/* sign extend */
  1904.                             if(*((long*)es) & tsfields[pc[2]])
  1905.                             {
  1906.                                 *((long*)es) |= sfields[pc[2]];
  1907.                                 ((long*)es)[1] = 0xffffffff;
  1908.                             }
  1909.                             else ((long*)es)[1] = 0;
  1910.                         }
  1911.                     }
  1912.                     else
  1913.                     {
  1914. #if SUPPORT_LONG_LONG
  1915.                             *((long long*)es) >>= pc[1];
  1916.                             *((long long*)es) &= lbfields[pc[2]];
  1917.                             if(pc[3])
  1918.                             {
  1919.                                 if(*((long long*)es) & ltsfields[pc[2]])
  1920.                                     *((long long*)es) |= lsfields[pc[2]];
  1921.                             }
  1922. #else
  1923. #endif
  1924.                     }
  1925.                     pc += 3;
  1926.                     break;
  1927.                 }
  1928.                 case PUTBITFIELD:
  1929.                 {
  1930.                     if(pc[1] + pc[2] <= 32)
  1931.                     {
  1932.                     unsigned long mask = bfields[pc[2]];
  1933.                     void *dst = *((void **)oes);
  1934.                     unsigned long dat = *((long*)es);
  1935.                         dat &= mask;
  1936.                         dat <<= pc[1];
  1937.                         mask <<= pc[1];
  1938.                         switch(pc[3])
  1939.                         {
  1940.                             case    1:
  1941.                                 *((char*)dst) &= ~mask;
  1942.                                 *((char*)dst) |= dat;
  1943.                                 break;
  1944.                             case    2:
  1945.                                 *((short*)dst) &= ~mask;
  1946.                                 *((short*)dst) |= dat;
  1947.                                 break;
  1948.                             case    4:
  1949.                                 *((long*)dst) &= ~mask;
  1950.                                 *((long*)dst) |= dat;
  1951.                                 break;
  1952.                             default:
  1953.                                 break;
  1954.                         }
  1955.                     }
  1956.                     else
  1957.                     {
  1958. #if SUPPORT_LONG_LONG
  1959.                     unsigned long long mask = lbfields[pc[2]];
  1960.                     void *dst = *((void **)oes);
  1961.                     unsigned long long dat = *((unsigned long long *)es);
  1962.                         dat &= mask;
  1963.                         dat <<= pc[1];
  1964.                         mask <<= pc[1];
  1965.                         switch(pc[3])
  1966.                         {
  1967.                             case    1:
  1968.                                 *((char*)dst) &= ~mask;
  1969.                                 *((char*)dst) |= dat;
  1970.                                 break;
  1971.                             case    2:
  1972.                                 *((short*)dst) &= ~mask;
  1973.                                 *((short*)dst) |= dat;
  1974.                                 break;
  1975.                             case    4:
  1976.                                 *((long*)dst) &= ~mask;
  1977.                                 *((long*)dst) |= dat;
  1978.                                 break;
  1979.                             case    8:
  1980.                                 *((long long*)dst) &= ~mask;
  1981.                                 *((long long*)dst) |= dat;
  1982.                                 break;
  1983.                             default:
  1984.                                 break;
  1985.                         }
  1986. #else
  1987. #endif
  1988.                     }
  1989.                     pc += 3;
  1990.                     es -= 2*SZ;
  1991.                     break;
  1992.                 }
  1993. #if SUPPORT_LONG_DOUBLE
  1994.                 case LI:
  1995.                     LOADIX();
  1996. #endif
  1997.                 case IMMED:
  1998.                 {
  1999.                     ++pc;
  2000.                     ++np;
  2001.                     switch(*pc)
  2002.                     {
  2003. #if SUPPORT_LONG_DOUBLE
  2004.  
  2005.                         case SMI|A1:
  2006.                             STORMEMI1(long double);
  2007.                         case SMI|A2:
  2008.                             STORMEMI2(long double);
  2009.                         case SMI|A3:
  2010.                             STORMEMI3(long double);
  2011.                         case SMI|A4:
  2012.                             STORMEMI4(long double);
  2013.  
  2014.                         case SSI|A1:
  2015.                             STORSTKI1(long double);
  2016.                         case SSI|A2:
  2017.                             STORSTKI2(long double);
  2018.                         case SSI|A3:
  2019.                             STORSTKI3(long double);
  2020.  
  2021.                         case DEREF|LONGDOUBLE:
  2022.                             FDEREF_ES(long double);
  2023.                         case DEREF1|LONGDOUBLE:
  2024.                             FDEREF1_ES(long double);
  2025. #endif
  2026. #if SUPPORT_LONG_LONG
  2027.                         case DEREF|LONGLONG:
  2028.                         case DEREF|ULONGLONG:
  2029.                             FDEREF_ES(long long);
  2030.  
  2031.                         case DEREF1|LONGLONG:
  2032.                         case DEREF1|ULONGLONG:
  2033.                             FDEREF1_ES(long long);
  2034.  
  2035.                         case MODI|LONGLONG:
  2036.                             MODI_ES(long long);
  2037.                         case MODI|ULONGLONG:
  2038.                             MODI_ES(unsigned long long);
  2039. #endif
  2040.                     }
  2041.                     break;
  2042.                 }/* END: XTD IMMED */
  2043. #if SUPPORT_LONG_LONG
  2044.                 
  2045.                 case ADD|LONGLONG:
  2046.                     ADD_ES(long long);
  2047.                 case ADD|ULONGLONG:
  2048.                     ADD_ES(unsigned long long);
  2049.                 case SUB|LONGLONG:
  2050.                     SUB_ES(long long);
  2051.                 case SUB|ULONGLONG:
  2052.                     SUB_ES(unsigned long long);
  2053.                 case MUL|LONGLONG:
  2054.                     MUL_ES(long long);
  2055.                 case MUL|ULONGLONG:
  2056.                     MUL_ES(unsigned long long);
  2057.                 case DIV|LONGLONG:
  2058.                     DIV_ES(long long);
  2059.                 case DIV|ULONGLONG:
  2060.                     DIV_ES(unsigned long long);
  2061.                 case NEG|LONGLONG:
  2062.                     NEG_ES(long long);
  2063.                 case NEG|ULONGLONG:
  2064.                     NEG_ES(unsigned long long);
  2065.                 case LT|LONGLONG:
  2066.                     LT_ES(long long);
  2067.                 case LT|ULONGLONG:
  2068.                     LT_ES(unsigned long long);
  2069.                 case GT|LONGLONG:
  2070.                     GT_ES(long long);
  2071.                  case GT|ULONGLONG:
  2072.                     GT_ES(unsigned long long);
  2073.                 case LE|LONGLONG:
  2074.                     LE_ES(long long);
  2075.                 case LE|ULONGLONG:
  2076.                     LE_ES(unsigned long long);
  2077.                 case GE|LONGLONG:
  2078.                     GE_ES(long long);
  2079.                 case GE|ULONGLONG:
  2080.                     GE_ES(unsigned long long);
  2081.                 case NE|LONGLONG:
  2082.                     NE_ES(long long);
  2083.                 case NE|ULONGLONG:
  2084.                     NE_ES(unsigned long long);
  2085.                 case EQ|LONGLONG:
  2086.                     EQ_ES(long long);
  2087.                 case EQ|ULONGLONG:
  2088.                     EQ_ES(unsigned long long);
  2089.                 case RSH|SLONGLONG:
  2090.                     RSH_ES(long long);
  2091.                 case RSH|SULONGLONG:
  2092.                     RSH_ES(unsigned long long);
  2093.  
  2094.                 case MOD|LONGLONG:
  2095.                     MODL_ES(long long);
  2096.                 case MOD|ULONGLONG:
  2097.                     MODL_ES(unsigned long long);
  2098.  
  2099.  
  2100.                 case RSHI|SLONGLONG:
  2101.                     RSHI_ES(long long);
  2102.                 case RSHI|SULONGLONG:
  2103.                     RSHI_ES(unsigned long long);
  2104. #endif
  2105.  
  2106. #if SUPPORT_LONG_DOUBLE
  2107.                 
  2108.                 case ADD|LONGDOUBLE:
  2109.                     ADD_ES(long double);
  2110.                 case SUB|LONGDOUBLE:
  2111.                     SUB_ES(long double);
  2112.                 case MUL|LONGDOUBLE:
  2113.                     MUL_ES(long double);
  2114.                 case DIV|LONGDOUBLE:
  2115.                     DIV_ES(long double);
  2116.                 case TRUTHOF|BX:
  2117.                     TRUTH_ES(long double);
  2118.                 case NOT|BX:
  2119.                     NOT_ES(long double);
  2120.                 case NEG|LONGDOUBLE:
  2121.                     NEG_ES(long double);
  2122.                 case LT|LONGDOUBLE:
  2123.                     LT_ES(long double);
  2124.                 case GT|LONGDOUBLE:
  2125.                     GT_ES(long double);
  2126.                 case LE|LONGDOUBLE:
  2127.                     LE_ES(long double);
  2128.                 case GE|LONGDOUBLE:
  2129.                     GE_ES(long double);
  2130.                 case NE|LONGDOUBLE:
  2131.                     NE_ES(long double);
  2132.                 case EQ|LONGDOUBLE:
  2133.                     EQ_ES(long double);
  2134.  
  2135.                 case LS|A1:
  2136.                     LOADSTK1(long double);
  2137.                 case LS|A2:
  2138.                     LOADSTK2(long double);
  2139.                 case LS|A3:
  2140.                     LOADSTK3(long double);
  2141.  
  2142.                 case LM|A1:
  2143.                     LOADMEM1(long double);
  2144.                 case LM|A2:
  2145.                     LOADMEM2(long double);
  2146.                 case LM|A3:
  2147.                     LOADMEM3(long double);
  2148.                 case LM|A4:
  2149.                     LOADMEM4(long double);
  2150.  
  2151.                 case SS|A1:
  2152.                     STORSTK1(long double);
  2153.                 case SS|A2:
  2154.                     STORSTK2(long double);
  2155.                 case SS|A3:
  2156.                     STORSTK3(long double);
  2157.  
  2158.                 case SM|A1:
  2159.                     STORMEM1(long double);
  2160.                 case SM|A2:
  2161.                     STORMEM2(long double);
  2162.                 case SM|A3:
  2163.                     STORMEM3(long double);
  2164.                 case SM|A4:
  2165.                     STORMEM4(long double);
  2166.  
  2167.                 case MOVSS:
  2168.                 {
  2169.                     pc += mover(iv, np+1, *np, BX, fs, fs);
  2170.                     break;
  2171.                 }                
  2172.                 case MOVSM:
  2173.                 {
  2174.                     pc += mover(iv, np+1, *np, BX, fs, dd);
  2175.                     break;
  2176.                 }
  2177.                 case MOVMS:
  2178.                 {
  2179.                     pc += mover(iv, np+1, *np, BX, dd, fs);
  2180.                     break;
  2181.                 }
  2182.                 case MOVMM:
  2183.                 {
  2184.                     pc += mover(iv, np+1, *np, BX, dd, dd);
  2185.                     break;
  2186.                 }
  2187. #endif /* SUPPORT_LONG_DOUBLE */
  2188.             }
  2189.             break;
  2190.         }/* END: XTD */
  2191.  
  2192.         case GT|BYTE:
  2193.             GT_ES(char);
  2194.         case GT|SHORT:
  2195.             GT_ES(short);
  2196.         case GT|LONG:
  2197.             GT_ES(long);
  2198.         case GT|UBYTE:
  2199.             GT_ES(unsigned char);
  2200.         case GT|USHORT:
  2201.             GT_ES(unsigned short);
  2202.         case GT|ULONG:
  2203.             GT_ES(unsigned long);
  2204.         case GT|FLOAT:
  2205.             GT_ES(float);
  2206.         case GT|DOUBLE:
  2207.             GT_ES(double);
  2208.  
  2209.         case LT|BYTE:
  2210.             LT_ES(char);
  2211.         case LT|SHORT:
  2212.             LT_ES(short);
  2213.         case LT|LONG:
  2214.             LT_ES(long);
  2215.         case LT|UBYTE:
  2216.             LT_ES(unsigned char);
  2217.         case LT|USHORT:
  2218.             LT_ES(unsigned short);
  2219.         case LT|ULONG:
  2220.             LT_ES(unsigned long);
  2221.         case LT|FLOAT:
  2222.             LT_ES(float);
  2223.         case LT|DOUBLE:
  2224.             LT_ES(double);
  2225.  
  2226.         case GE|BYTE:
  2227.             GE_ES(char);
  2228.         case GE|SHORT:
  2229.             GE_ES(short);
  2230.         case GE|LONG:
  2231.             GE_ES(long);
  2232.         case GE|UBYTE:
  2233.             GE_ES(unsigned char);
  2234.         case GE|USHORT:
  2235.             GE_ES(unsigned short);
  2236.         case GE|ULONG:
  2237.             GE_ES(unsigned long);
  2238.         case GE|FLOAT:
  2239.             GE_ES(float);
  2240.         case GE|DOUBLE:
  2241.             GE_ES(double);
  2242.  
  2243.         case LE|BYTE:
  2244.             LE_ES(char);
  2245.         case LE|SHORT:
  2246.             LE_ES(short);
  2247.         case LE|LONG:
  2248.             LE_ES(long);
  2249.         case LE|UBYTE:
  2250.             LE_ES(unsigned char);
  2251.         case LE|USHORT:
  2252.             LE_ES(unsigned short);
  2253.         case LE|ULONG:
  2254.             LE_ES(unsigned long);
  2255.         case LE|FLOAT:
  2256.             LE_ES(float);
  2257.         case LE|DOUBLE:
  2258.             LE_ES(double);
  2259.  
  2260.         case NE|BYTE:
  2261.             NE_ES(char);
  2262.         case NE|SHORT:
  2263.             NE_ES(short);
  2264.         case NE|LONG:
  2265.             NE_ES(long);
  2266.         case NE|UBYTE:
  2267.             NE_ES(unsigned char);
  2268.         case NE|USHORT:
  2269.             NE_ES(unsigned short);
  2270.         case NE|ULONG:
  2271.             NE_ES(unsigned long);
  2272.         case NE|FLOAT:
  2273.             NE_ES(float);
  2274.         case NE|DOUBLE:
  2275.             NE_ES(double);
  2276.  
  2277.         case EQ|BYTE:
  2278.             EQ_ES(char);
  2279.         case EQ|SHORT:
  2280.             EQ_ES(short);
  2281.         case EQ|LONG:
  2282.             EQ_ES(long);
  2283.         case EQ|UBYTE:
  2284.             EQ_ES(unsigned char);
  2285.         case EQ|USHORT:
  2286.             EQ_ES(unsigned short);
  2287.         case EQ|ULONG:
  2288.             EQ_ES(unsigned long);
  2289.         case EQ|FLOAT:
  2290.             EQ_ES(float);
  2291.         case EQ|DOUBLE:
  2292.             EQ_ES(double);
  2293.  
  2294.         case ARG:
  2295.         case ARGA:
  2296.         case ARGF:
  2297.         {
  2298.         PCB cb = (PCB)(es-(3*SZ));
  2299.         long size = *((long*)es);
  2300.         void *src = oes-SZ;
  2301.         void *dst;
  2302.             if(cb->flags & 0x80)
  2303.             {/* arg to builtin func */
  2304.                 cb->es += SZ;
  2305.                 dst = cb->es;
  2306.             }
  2307.             else
  2308.             {
  2309.                 dst = cb->base_stack+sizeof(SB)+(cb->argofs<<2)+*((long*)oes);
  2310.             }
  2311.             if(*pc == ARGA)
  2312.             {/* dereference */
  2313.                 src = *((void**)src);
  2314.             }
  2315.             else if(*pc == ARGF)
  2316.             {/* Passing address of function */
  2317.             Pft ft = *((Pft*)src);
  2318.  
  2319.               if(ft->fmods & Fnested)
  2320.               {/* Record the current evaluation stack
  2321.                       the nested func will be called back */
  2322.                 ((PSB)base_stack)->cbes = (void*)cb;
  2323.               }
  2324.               if(cb->flags & 0x40)
  2325.               {/* To an external function */
  2326.                 if(!(ft->fmods & Fextern))
  2327.                 {/* Passing address of local function */
  2328.                   if(!(ft->fmods & Fthunked))
  2329.                   {
  2330.                     *((void**)src) = make_callback_thunk(    iv,
  2331.                                                             base_stack,
  2332.                                                             ft);
  2333.                     ft->fmods |= Fthunked;
  2334.                     if(ft->fmods & Fnested)
  2335.                     {/* The thunk will be freed later */
  2336.                         ((PSB)base_stack)->thunkaddr = *((void**)src);
  2337.                     }
  2338.                   }
  2339.                 }
  2340.               }
  2341.             }/* END: *pc == ARGF */
  2342.             switch(size)
  2343.             {
  2344.                 case 1:
  2345.                     *((char*)dst) = *((char*)src);
  2346.                     break;
  2347.                 case 2:
  2348.                     *((short*)dst) = *((short*)src);
  2349.                     break;
  2350.                 case 4:
  2351.                     *((long*)dst) = *((long*)src);
  2352.                     break;
  2353.                 case 8:
  2354.                     *((double*)dst) = *((double*)src);
  2355.                     break;
  2356.                 default:
  2357.                     memcpy(dst, src, size);
  2358.                     break;
  2359.             }
  2360.             es -= 3*SZ;
  2361.             break;
  2362.         }
  2363.  
  2364.         case MOVSS|B1:
  2365.         case MOVSS|B2:
  2366.         case MOVSS|B4:
  2367.         case MOVSS|B8:
  2368.         {
  2369.             pc += mover(iv, np+1, *np, *pc & 3, fs, fs);
  2370.             break;
  2371.         }
  2372.         case MOVSM|B1:
  2373.         case MOVSM|B2:
  2374.         case MOVSM|B4:
  2375.         case MOVSM|B8:
  2376.         {
  2377.             pc += mover(iv, np+1, *np, *pc & 3, fs, dd);
  2378.             break;
  2379.         }
  2380.         case MOVMS|B1:
  2381.         case MOVMS|B2:
  2382.         case MOVMS|B4:
  2383.         case MOVMS|B8:
  2384.         {
  2385.             pc += mover(iv, np+1, *np, *pc & 3, dd, fs);
  2386.             break;
  2387.         }        
  2388.         case MOVMM|B1:
  2389.         case MOVMM|B2:
  2390.         case MOVMM|B4:
  2391.         case MOVMM|B8:
  2392.         {
  2393.             pc += mover(iv, np+1, *np, *pc & 3, dd, dd);
  2394.             break;
  2395.         }
  2396.         case DUMP:
  2397.         {
  2398.             es = oes;
  2399.             break;
  2400.         }
  2401.         case REGAIN:
  2402.         {
  2403.             es = nes;
  2404.             break;
  2405.         }
  2406.         case CALL:
  2407.         {
  2408.         PCB cb = (PCB)es;
  2409.         Pft ft = cb->loc;
  2410.           if(cb->flags & 0x80)
  2411.           {/* call builtin function through a function pointer */
  2412.           char *pes = cb->es;
  2413.  
  2414.             if(do_builtin(iv, (unsigned char)ft->funcaddr, &pes))
  2415.             {/* builtin returned something */
  2416. #if SUPPORT_LONG_DOUBLE
  2417.                 *((long double*)es) = *((long double*)(pes));
  2418. #else
  2419.                 *((double*)es) = *((double*)pes);
  2420. #endif
  2421.             }
  2422.             free(cb->base_stack);
  2423.           }
  2424.           else if(cb->flags & 0x40)
  2425.           {/* call external function */
  2426.           unsigned short fmods = ft->fmods;
  2427.           DATUM lastval;
  2428.             if(fmods & Fretstr)
  2429.             {
  2430.               _ExternCallS(    ft->funcaddr, 
  2431.                             cb->base_stack+sizeof(SB), 
  2432.                             cb->argsiz,
  2433.                             &lastval);
  2434.             }
  2435.             else
  2436.             {
  2437.               _ExternCall(    ft->funcaddr, 
  2438.                             cb->base_stack+sizeof(SB), 
  2439.                             cb->argsiz,
  2440.                             &lastval);
  2441.             }
  2442.             if(fmods & Fretdbl)
  2443.             {
  2444.                 asm ("fstpl %0" : "=g"(lastval.Udouble) :);
  2445.             }
  2446.             else if(fmods & Fretflt)
  2447.             {
  2448.                 asm ("fstps %0" : "=g"(lastval.Ufloat) :);
  2449.             }
  2450.             else if(fmods & Fretldbl)
  2451.             {
  2452. #if SUPPORT_LONG_DOUBLE
  2453.                 asm ("fstpt %0" : "=g"(lastval.Ulongdouble) :);
  2454. #else
  2455.                 asm ("fstpl %0" : "=g"(lastval.Udouble) :);
  2456. #endif
  2457.             }
  2458. #if SUPPORT_LONG_DOUBLE
  2459.             *((long double*)es) = lastval.Ulongdouble;
  2460. #else
  2461.             *((double*)es) = lastval.Udouble;
  2462. #endif
  2463.             free(cb->base_stack);
  2464.           }/* END: call external func */
  2465.           else
  2466.           { /* call internal function */
  2467.           void *pes;
  2468.           void *lastalloca = iv->allocalist;
  2469.             pes = bterp_eval(iv, ft->funcaddr, cb->base_stack, cb->es, 
  2470.                 cb->base_stack+((PSB)cb->base_stack)->stksize);
  2471. #if SUPPORT_LONG_DOUBLE
  2472.             *((long double*)es) = *((long double*)pes);
  2473. #else
  2474.             *((double*)es) = *((double*)pes);
  2475. #endif
  2476.             if(cb->flags & 0x20)
  2477.             {/* calledback a nested function */
  2478.  
  2479.             }
  2480.             else if(!(cb->flags & 0x10))
  2481.             {/* called interpreted function */
  2482.                 free(cb->base_stack);
  2483.             } 
  2484.             purge_allocas(iv, lastalloca);
  2485.           }/* END: call internal function */
  2486.           break;
  2487.         }
  2488.         case RET:
  2489.         {
  2490. if(iv->debug) {
  2491. printf("RET ofs=%lx es=%p val=0x%lx\n", pc_offset, es, *((long*)es));
  2492. fflush(stdout);
  2493. }
  2494.             return es;
  2495.         }
  2496.         case SWAP:
  2497.         {
  2498.         char t[SZ];
  2499.             memcpy(t,es,SZ);
  2500.             memcpy(es,oes,SZ);
  2501.             memcpy(oes,t,SZ);
  2502.             break;
  2503.         }    
  2504.         case SWAP4:
  2505.         {
  2506.         long x;
  2507.             x = *((long *)es);
  2508.             *((long*)es) = *((long*)oes);
  2509.             *((long*)oes) = x;
  2510.             break;
  2511.         }
  2512.         case SWAP4DEEP:
  2513.         {
  2514.         long x;
  2515.             x = *((long*)oes);
  2516.             *((long*)oes) = *((long*)(oes-SZ));
  2517.             *((long*)(oes-SZ)) = x;
  2518.             break;
  2519.         }
  2520.         case DUP:
  2521.         {
  2522.             memcpy(nes,es,SZ);
  2523.             es = nes;
  2524.             break;
  2525.         }
  2526.         case DUP4:
  2527.         {
  2528.             *((long*)nes) = *((long*)es);
  2529.             es = nes;
  2530.             break;
  2531.         }
  2532.         case ABSMEM:
  2533.         {
  2534.             *((unsigned long*)es) += (unsigned long)dd;
  2535.             break;
  2536.         }
  2537.         case ABSSTK:
  2538.         {
  2539.             *((unsigned long*)es) += (unsigned long)fs;
  2540.             break;
  2541.         }
  2542.         case MOVDA1:
  2543.         {
  2544.             **((char**)(oes)) = *((char*)es);    
  2545.             es -= 2*SZ;
  2546.             break;
  2547.         }
  2548.         case MOVDA2:
  2549.         {
  2550.             **((short**)(oes)) = *((short*)es);    
  2551.             es -= 2*SZ;
  2552.             break;
  2553.         }
  2554.         case MOVDA4:
  2555.         {
  2556.             **((long**)(oes)) = *((long*)es);    
  2557.             es -= 2*SZ;
  2558.             break;
  2559.         }
  2560.         case MOVDA8:
  2561.         {
  2562.             **((double**)(oes)) = *((double*)es);    
  2563.             es -= 2*SZ;
  2564.             break;
  2565.         }
  2566.         case MOVDAX:
  2567.         {
  2568. #if SUPPORT_LONG_DOUBLE
  2569.             **((long double**)(oes)) = *((long double*)es);    
  2570. #else
  2571.             memcpy(*((void**)(oes)), es, XSZ);
  2572. #endif
  2573.             es -= 2*SZ;
  2574.             break;
  2575.         }
  2576.         case MOVAA1:
  2577.         {
  2578.             **((char**)(oes)) = **((char**)es);    
  2579.             es -= 2*SZ;
  2580.             break;
  2581.         }
  2582.         case MOVAA2:
  2583.         {
  2584.             **((short**)(oes)) = **((short**)es);    
  2585.             es -= 2*SZ;
  2586.             break;
  2587.         }
  2588.         case MOVAA4:
  2589.         {
  2590.             **((long**)(oes)) = **((long**)es);    
  2591.             es -= 2*SZ;
  2592.             break;
  2593.         }
  2594.         case MOVAA8:
  2595.         {
  2596.             **((double**)(oes)) = **((double**)es);    
  2597.             es -= 2*SZ;
  2598.             break;
  2599.         }
  2600.         case MOVAAX:
  2601.         {
  2602. #if SUPPORT_LONG_DOUBLE
  2603.             **((long double**)(oes)) = **((long double**)es);    
  2604. #else
  2605.             memcpy(*((void**)(oes)), *((void**)es), XSZ);
  2606. #endif
  2607.             es -= 2*SZ;
  2608.             break;
  2609.         }
  2610.         case MOVAAC:
  2611.         {
  2612.             memcpy(*((void**)(es-(2*SZ))), *((void**)(oes)), *((long*)(es)));
  2613.             es -= 3*SZ;
  2614.             break;
  2615.         }
  2616.     }
  2617.   }/* END: for(;;++pc) */
  2618. /* NOT REACHED */
  2619.   return 0;
  2620. }/* END: bterp_eval() */
  2621. /* ====================== END INTERPRETER CODE ===================== */
  2622.  
  2623. /* ==================  INITIALIZATION CODE BELOW THIS POINT ================ */
  2624. static Piv tiv;    /* temporary storage of iv whilst calling oxlink */
  2625.  
  2626. int 
  2627. bterp_setup_functhunk(FE entry, struct nlist *nl)
  2628. {/* Called from the dynamic linker */
  2629. Pft ft;
  2630.  
  2631.     ft = (void*)(entry->data_start_address + nl->n_value);
  2632.  
  2633.     if(ft->fmods & Fextern)
  2634.     {/* store a pointer to the function name string */
  2635.         if(!(ft->fmods & Fthunked))
  2636.         {
  2637.             ft->funcaddr = (long)(entry->strings + nl->n_un.n_strx);
  2638.         }
  2639.         return 0;
  2640.     }
  2641.     else if(!(ft->fmods & Fthunked))
  2642.     {/* export a useful address */
  2643.         nl->n_value = (long)make_callback_thunk(tiv, 0, ft);
  2644.         ft->fmods |= Fthunked;
  2645.     }
  2646.     return 1;
  2647. }
  2648. void
  2649. bterp_setup_switch(FE entry, struct nlist *nl)
  2650. {/* Called from the dynamic linker */
  2651. unsigned long key[2];
  2652. long value;
  2653.  
  2654.     if(tiv->swtable == 0)
  2655.         tiv->swtable = calloc(1, SWITCHMOD*sizeof(void*));
  2656.  
  2657.     key[0] = nl->n_desc<<11;
  2658.     key[1] = nl->n_un.n_strx;
  2659.     value = (long)(entry->text_start_address + nl->n_value);
  2660.     saveswitch(tiv, key, value);    
  2661. }
  2662.  
  2663. /* ====================== THE MAIN PROGRAM =============================== */
  2664.  
  2665. static char *
  2666. filenameof(char *path)
  2667. {
  2668. char *ret = path;
  2669. int i = strlen(path)-1;
  2670.  
  2671.     for( ; i >= 0; --i)
  2672.       if(path[i] == '/' || path[i] == '\\' || path[i] == ':')
  2673.         ret = &path[i+1];
  2674.     return ret;
  2675. }
  2676.  
  2677. static char *
  2678. propernameof(char *path)
  2679. {
  2680. int pathlen = strlen(path);
  2681. char *name = malloc(pathlen+8);
  2682. int i;
  2683.  
  2684.     strcpy(name, path);
  2685.     for(i = pathlen-1; i >= 0; --i)
  2686.     {
  2687.       if(name[i] == '/' || name[i] == '\\' || name[i] == ':')
  2688.           break;
  2689.       else if(name[i] == '.')
  2690.         return name;
  2691.     }
  2692.     strcat(name, ".byt");
  2693.     return name;
  2694. }
  2695. static char *
  2696. basenameof(char *filename)
  2697. {
  2698. char *name = malloc(strlen(filename)+8);
  2699. int i;
  2700.     strcpy(name, filename);
  2701.     for(i = 0; name[i]; ++i)
  2702.       if(name[i] == '.')
  2703.         name[i] = 0;
  2704.     return name;
  2705. }
  2706. static void
  2707. setup_run_args(Piv iv, int argc, char **argv, char *startname)
  2708. {
  2709. int i;
  2710.  
  2711.     if(!startname)
  2712.     {
  2713.         startname = basenameof(filenameof(argv[1]));
  2714.     }
  2715.     iv->run_argcnt = argc - 1;
  2716.     if(iv->run_argcnt > MAX_RUNARGS)
  2717.         iv->run_argcnt = MAX_RUNARGS;
  2718.     iv->run_args[0] = startname;
  2719.     for(i = 1; i < iv->run_argcnt; ++i)
  2720.     {
  2721.         iv->run_args[i] = argv[i+1];
  2722.     }
  2723. }
  2724. static void
  2725. Usage()
  2726. {
  2727. puts(
  2728. "Usage: bterp [+Sd] file [args]...\n"
  2729. "   +S name == start execution at function `name'\n"
  2730. "   +d      == print debug stmts\n"
  2731. "   Default execution starts at function `file'\n"
  2732. );
  2733. }
  2734. #if USING_FRAMEWORK
  2735. int
  2736. PROG (int argc, char **argv)
  2737. #else
  2738. int
  2739. main(int argc, char **argv)
  2740. #endif
  2741. {
  2742. int i, j;
  2743. char *startname;
  2744. long *argptr;
  2745. long es_beg, fs_size;
  2746. int *pes, ret;
  2747. Piv iv;
  2748.  
  2749.     iv = tiv = calloc(1, sizeof(struct _iv));
  2750.     iv->piv = iv;
  2751.  
  2752.     startname = 0;
  2753.     for(i = 1; i < argc; ++i)
  2754.     {
  2755.     int trimsize = 1;
  2756.         if(argv[i][0] == '+')
  2757.         {
  2758.             for (j=1; argv[i][j]; j++)
  2759.             {
  2760.                 switch(argv[i][j])
  2761.                 {    
  2762.                     case    'd':
  2763.                         iv->debug = 1;
  2764.                         break;
  2765.                     case    'S':
  2766.                         if(argv[i][j+1]) {
  2767.                             startname = &argv[i][j+1];
  2768.                         }
  2769.                         else if(i < argc-1) {
  2770.                             startname = argv[i+1];
  2771.                             trimsize = 2;
  2772.                         } else {
  2773.                             printf("bterp:ERROR: No starting fuction name\n");
  2774.                             Usage();
  2775.                             return 1;
  2776.                         }
  2777.                         goto trim;
  2778.                         break;
  2779.                 }
  2780.             }
  2781. trim:
  2782.             /* Trim switch */
  2783.             for(j = i; j < argc-trimsize; ++j)
  2784.                 argv[j] = argv[j+trimsize];
  2785.             argc -= trimsize;
  2786.             --i;    /* i will be bumped by for */
  2787.         }
  2788.     }
  2789.     if(argc > 1)
  2790.     {
  2791.     PSB sp;
  2792.         iv->filename = propernameof(argv[1]);
  2793.         if(oxlink_load_object(iv->filename))        /* try library list */
  2794.         {
  2795.             oxlink_demand_noload();
  2796.             if(oxlink_load_file(iv->filename))        /* try search path */
  2797.             {
  2798.                 printf("bterp:ERROR: file `%s' %s\n", iv->filename, oxlink_errstr());
  2799.                 exit(1);
  2800.             }
  2801.             oxlink_demand_load();
  2802.         }
  2803.         iv->entry = oxlink_get_entry_struct(iv->filename);
  2804.         iv->text_base = iv->entry->text_start_address;
  2805.         iv->dd = iv->entry->data_start_address;
  2806.  
  2807.         setup_run_args(iv, argc, argv, startname);
  2808.         if(!(iv->funcptr = oxlink_find_func("main")))
  2809.         {
  2810.           if(!(iv->funcptr = oxlink_find_func(iv->run_args[0])))
  2811.           {
  2812.             printf("bterp:ERROR: function `%s' not found in file\n", iv->run_args[0]);
  2813.             oxlink_unload_file(iv->filename, 0);
  2814.             free(iv->filename);
  2815.             free(iv->run_args[0]);
  2816.             free(iv);
  2817.             return 1;
  2818.           }
  2819.         }
  2820.         iv->ft = *((Pft*)(&iv->funcptr[4]));
  2821.         iv->funcaddr = iv->ft->funcaddr;
  2822.         iv->stksiz = iv->ft->stksiz<<2;
  2823.         iv->argsiz = iv->ft->argsiz<<2;
  2824.         iv->maxes = iv->ft->maxes;
  2825.  
  2826.         es_beg = iv->stksiz+iv->argsiz;
  2827.         fs_size = es_beg + ((iv->maxes+6)*SZ);
  2828.         iv->base_stack = calloc(1, fs_size + sizeof(SB));
  2829.         iv->e_stack = iv->base_stack + sizeof(SB) + es_beg;
  2830.  
  2831.         /* Fill in _stakblk */
  2832.         sp = (PSB)iv->base_stack;
  2833.         sp->first_loc = iv->funcaddr;
  2834.         sp->last_loc = iv->dd - iv->text_base;
  2835.         sp->stksize = fs_size + sizeof(SB);
  2836.  
  2837.         /* Fill in the arguments */
  2838.         argptr = (long*)(iv->base_stack + iv->stksiz + sizeof(SB));
  2839.         if(iv->argsiz >= 4)
  2840.             argptr[0] = iv->run_argcnt;
  2841.         if(iv->argsiz >= 8)
  2842.             argptr[1] = (long)iv->run_args;
  2843.  
  2844.         if((pes = (void*)setjmp(iv->jb)))
  2845.             goto done;
  2846.  
  2847.         /* Call the starting function */
  2848.         pes = bterp_eval(iv, iv->funcaddr, iv->base_stack, iv->e_stack,
  2849.                 iv->base_stack + (fs_size+sizeof(SB)));
  2850. done:
  2851.         ret = *pes;
  2852.         prune_structs(iv);
  2853.         oxlink_unload_file(iv->filename, 0);
  2854.         free(iv->filename);
  2855.         free(iv->run_args[0]);
  2856.         free(iv->base_stack);
  2857.         if(iv->swtable)
  2858.         {
  2859.         void *p = iv->chunklist;
  2860.             free(iv->swtable);
  2861.             while(p)
  2862.             {
  2863.             void *q = p;
  2864.                 p = *((void**)p);
  2865.                 free(q);
  2866.             }
  2867.         }
  2868.         free(iv);
  2869.         return ret;
  2870.     }
  2871.     else
  2872.     {
  2873.         Usage();
  2874.         return 1;
  2875.     }
  2876. }
  2877. #if 0 /* used for testing */
  2878. int bterpcallback(int (*pfunc)())
  2879. {
  2880.     return pfunc();
  2881. }
  2882. #endif
  2883.